Commit cb6a3d5a by John Doe

working on db parsing

parent 75bcc2b7
--color
--require spec_helper
--format documentation
\ No newline at end of file
......@@ -16,7 +16,8 @@ class DbAdapter
start_time: entry[2] || 0,
end_time: entry[3] || 0,
total_rows: entry[4],
total_time: entry[5] }
total_time: entry[5],
metadata: {} }
end
end
end
......@@ -2,56 +2,95 @@
# Handles construction of database objects
class DbBuilder
def initialize(db:, db_service:)
def initialize(db:)
@db = db
@db_service = db_service
end
def update_db
entries = @db_service.schema
#split path into chunks
entries.map! do |entry|
def update_db(schema:)
# split path into chunks
entries = schema.map do |entry|
entry[:chunks] = entry[:path][1..-1].split('/').reverse
entry
end
if(@db.root_folder == nil)
@db.root_folder=__build_folder(entries: entries, default_name: 'root')
end
#group entries by first chunk
#find or create an entry with the single chunk 'info'
#if the group contains one entry that is *not* 'info', make it a file
#if the group contains multiple entries, make it a folder
#..recursive
# create the root folder if it doesn't exist
@db.root_folder ||= DbFolder.create(name: 'root', path: '/')
@root_folder = @db.root_folder
# add the folder entries
__parse_folder_entries(parent: nil, entries: entries)
end
protected
def __build_folder(entries:, default_name:)
folder = DbFolder.new(name: default_name)
entry_groups = Hash.new()
entries.map do |entry|
__add_to_group(entry_groups, entry[:chunks].pop, entry)
end
entry_groups.each do |name, entry_group|
if(entry_group.length==1)
folder.db_files << __build_file(entry: entry_group, default_name: name)
elsif(entry_group.length > 1)
folder.subfolders << __build_folder(entries: entry_group, default_name: name)
def __parse_folder_entries(parent:, entries:, default_name: '')
# find the info stream entry if it exists
info = __read_info_entry(entries) || { name: default_name }
# generate the folder path
path = __build_path(entries)
# create or update the folder
folder = __build_folder(parent: parent, path: path, info: info)
# group the folder entries
groups = __group_entries(entries)
# convert the entries into subfolders and files
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
folder
end
def __read_info_entry(entries)
if entries[0][:chunks] == ['info']
info_entry = entries.slice!(0)
info_entry[:metadata]
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
# up to the point where they still have
# chunks. Get this common path by popping
# the chunks off the first entry's path
parts = entries[0][:path].split('/')
parts.pop(entries[0][:chunks].length)
parts.join('/') # stitch parts together to form a path
end
def __group_entries(entries)
entry_groups = {}
entries.map do |entry|
__add_to_group(entry_groups, entry[:chunks].pop, entry)
end
entry_groups
end
def __add_to_group(entry_groups, group_name, entry)
if entry_groups[group_name] == nil
entry_groups[group_name] = [entry]
entry_groups[group_name] ||= []
if entry[:chunks] == ['info'] # put the info stream in front
entry_groups[group_name].prepend(entry)
else
entry_groups[group_name].push(entry)
entry_groups[group_name].append(entry)
end
end
def __build_file(entry:, default_name:)
file = DbFile.new(name: default_name)
end
end
......@@ -4,7 +4,7 @@
# and one or more DbFolders as subfolders
class DbFolder < ActiveRecord::Base
belongs_to :parent, class_name: 'DbFolder'
has_many :subfolders, class_name: 'DbFolder', foreign_key: 'db_folder_id'
has_many :subfolders, class_name: 'DbFolder', foreign_key: 'parent_id'
has_many :db_files
def insert_file(file:)
......
......@@ -8,7 +8,7 @@ describe DbAdapter do
adapter = DbAdapter.new(db.url)
adapter.schema.map do |entry|
expect(entry).to include(:path, :type, :start_time,
:end_time, :total_rows, :total_time)
:end_time, :total_rows, :total_time, :metadata)
end
end
end
# frozen_string_literal: true
require 'rails_helper'
helper = DbSchemaHelper.new
# schema data
def entry(path, type = 'uint8_1')
{ path: path, type: type,
start_time: 0, end_time: 0,
total_rows: 0, total_time: 0
}
end
simple_db = [
entry('/folder1/info'),
entry('/folder1/file1'),
entry('/folder1/file2'),
entry('/empty_folder/info')
]
# a simple schema that could be returned
# from DbAdapater.schema
simple_db = [ # folder1
helper.entry('/folder1/file1_1'), # `- file1_1
helper.entry('/folder1/file1_2'), # - file1_2
helper.entry('/folder2/file2_1'), # folder2
helper.entry('/folder2/file2_2'), # '- file2_1
] # `- file2_2
describe DbBuilder do
describe 'update_db' do
let(:db) { Db.new }
it 'initializes an empty database' do
db_service = instance_double('DbService', schema: simple_db)
db_builder = DbBuilder.new(db: db, db_service: db_service)
db_builder.update_db
expect(db.root_folder.name).to eq('root')
describe '*update_db*' do
before(:all) do
@db = Db.new
@db_builder = DbBuilder.new(db: @db)
end
describe 'given the simple_db schema' do
before(:all) do
@db_builder.update_db(schema: simple_db)
@root = @db.root_folder
end
it 'builds a root folder' do
expect(@root.name).to eq('root')
expect(@root.subfolders.count).to eq(2)
expect(@root.db_files.count).to eq(0)
end
it 'builds sub-folder1' do
folder1 = @root.subfolders[0]
expect(folder1.name).to eq('folder1')
expect(folder1.db_files.count).to eq(2)
expect(folder1.db_files[0].name).to eq('file1_1')
expect(folder1.db_files[1].name).to eq('file1_2')
end
it 'builds sub-folder2' do
folder2 = @root.subfolders[1]
expect(folder2.name).to eq('folder2')
expect(folder2.db_files.count).to eq(2)
expect(folder2.db_files[0].name).to eq('file2_1')
expect(folder2.db_files[1].name).to eq('file2_2')
end
end
describe 'given simple_db schema with folder info streams' do
before(:all) do
simple_db << helper.entry('/folder1/info', metadata: { name: 'first' })
simple_db << helper.entry('/folder2/info', metadata: { name: 'second' })
@db_builder.update_db(schema: simple_db)
end
it 'uses the name info'
end
end
end
# frozen_string_literal: true
# Helpers to produce database schemas that
# are usually returned by DbAdapter.schema
class DbSchemaHelper
# schema data
def entry(path, type: 'uint8_1', metadata: {})
{ path: path, type: type,
start_time: 0, end_time: 0,
total_rows: 0, total_time: 0,
metadata: metadata
}
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