Commit 60ff3dd1 by John Doe

refactored basic database parsing

parent cb6a3d5a
Showing with 67 additions and 34 deletions
...@@ -7,20 +7,33 @@ class DbBuilder ...@@ -7,20 +7,33 @@ class DbBuilder
end end
def update_db(schema:) def update_db(schema:)
# split path into chunks
entries = schema.map do |entry|
entry[:chunks] = entry[:path][1..-1].split('/').reverse
entry
end
# create the root folder if it doesn't exist # create the root folder if it doesn't exist
@db.root_folder ||= DbFolder.create(name: 'root', path: '/') @db.root_folder ||= DbFolder.create(name: 'root', path: '/')
@root_folder = @db.root_folder @root_folder = @db.root_folder
# add the folder entries
# create the entry array from the schema
entries = __create_entries(schema)
# parse the entries array
# Note: @root_folder gets linked in on
# the first call to __build_folder
__parse_folder_entries(parent: nil, entries: entries) __parse_folder_entries(parent: nil, entries: entries)
end end
protected protected
# Adds :chunks to each schema element
# :chunks is an array of the entry's path elements
# this makes it easier to traverse the database structure.
def __create_entries(schema)
schema.map do |entry|
entry[:chunks] = entry[:path][1..-1].split('/').reverse
entry
end
end
# Creates or updates the folder defined by these entries.
# Then adds in any subfolders or subfiles
def __parse_folder_entries(parent:, entries:, default_name: '') def __parse_folder_entries(parent:, entries:, default_name: '')
# find the info stream entry if it exists # find the info stream entry if it exists
info = __read_info_entry(entries) || { name: default_name } info = __read_info_entry(entries) || { name: default_name }
...@@ -30,20 +43,14 @@ class DbBuilder ...@@ -30,20 +43,14 @@ class DbBuilder
folder = __build_folder(parent: parent, path: path, info: info) folder = __build_folder(parent: parent, path: path, info: info)
# group the folder entries # group the folder entries
groups = __group_entries(entries) groups = __group_entries(entries)
# convert the entries into subfolders and files # process the groups as subfolders or files
groups.each do |name, entry_group| __process_folder_contents(folder, groups)
if entry_group.length == 1
folder.db_files << __build_file(folder: folder, entry: entry_group[0],
default_name: name)
elsif entry_group.length > 1
folder.subfolders << __parse_folder_entries(parent: folder,
entries: entry_group,
default_name: name)
end
end
folder folder
end end
# if this folder has an info stream, find that entry and
# use its metadata to update the folder's attributes
def __read_info_entry(entries) def __read_info_entry(entries)
if entries[0][:chunks] == ['info'] if entries[0][:chunks] == ['info']
info_entry = entries.slice!(0) info_entry = entries.slice!(0)
...@@ -51,32 +58,33 @@ class DbBuilder ...@@ -51,32 +58,33 @@ class DbBuilder
end end
end end
def __build_folder(parent:, path:, info:)
return @root_folder if parent.nil?
folder = parent.subfolders.find_by_path(path)
folder ||= DbFolder.new(parent: parent, path: path)
folder.update_attributes(info)
folder.save!
folder
end
def __build_file(folder:, entry:, default_name:)
file = folder.db_files.find_by_path(entry[:path])
file ||= DbFile.new(name: default_name)
file.save!
file
end
def __build_path(entries)
# all entries agree on a common path # all entries agree on a common path
# up to the point where they still have # up to the point where they still have
# chunks. Get this common path by popping # chunks. Get this common path by popping
# the chunks off the first entry's path # the chunks off the first entry's path
def __build_path(entries)
parts = entries[0][:path].split('/') parts = entries[0][:path].split('/')
parts.pop(entries[0][:chunks].length) parts.pop(entries[0][:chunks].length)
parts.join('/') # stitch parts together to form a path parts.join('/') # stitch parts together to form a path
end end
# create or update a DbFolder object at the
# specified path. If the parent parameter is nil
# then the folder must be the Db's root folder
def __build_folder(parent:, path:, info:)
return @root_folder if parent.nil?
folder = parent.subfolders.find_by_path(path)
folder ||= DbFolder.new(parent: parent, path: path)
folder.update_attributes(info)
folder.save!
folder
end
# collect the folder's entries into a set groups
# based off the next item in their :chunk array
# returns entry_groups which is a Hash with
# :key = name of the common chunk
# :value = the entry, less the common chunk
def __group_entries(entries) def __group_entries(entries)
entry_groups = {} entry_groups = {}
entries.map do |entry| entries.map do |entry|
...@@ -85,6 +93,8 @@ class DbBuilder ...@@ -85,6 +93,8 @@ class DbBuilder
entry_groups entry_groups
end end
# helper function to __group_entries that handles
# sorting entries into the entry_groups Hash
def __add_to_group(entry_groups, group_name, entry) def __add_to_group(entry_groups, group_name, entry)
entry_groups[group_name] ||= [] entry_groups[group_name] ||= []
if entry[:chunks] == ['info'] # put the info stream in front if entry[:chunks] == ['info'] # put the info stream in front
...@@ -93,4 +103,27 @@ class DbBuilder ...@@ -93,4 +103,27 @@ class DbBuilder
entry_groups[group_name].append(entry) entry_groups[group_name].append(entry)
end end
end end
# convert the groups into subfolders and files
def __process_folder_contents(folder, groups)
groups.each do |name, entry_group|
if entry_group.length == 1
folder.db_files << __build_file(folder: folder, entry: entry_group[0],
default_name: name)
elsif entry_group.length > 1
folder.subfolders << __parse_folder_entries(parent: folder,
entries: entry_group,
default_name: name)
end
end
end
# create or update a DbFile object at the
# specified path.
def __build_file(folder:, entry:, default_name:)
file = folder.db_files.find_by_path(entry[:path])
file ||= DbFile.new(name: default_name)
file.save!
file
end
end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment