I will be receiving a bunch of full paths to directories and files and need to build up a directory structure. This structure will be stored in SQL Server using an adjacency list in a table defined as:
CREATE TABLE [dbo].[DirTreeEntry]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[full_path] [nvarchar](2048) NOT NULL,
[name] [nvarchar](255) NOT NULL,
[is_file] [bit] NOT NULL,
[is_root] [bit] NOT NULL,
[parent_id] [int] NULL,
[source_id] [int] NULL
)
With id
being the primary key, name
in this case being the immediate name, not the full path, and source_id
referencing the source table entry if it explicitly exists there.
The source data will be in this table:
CREATE TABLE [dbo].[dir_path]
(
[dir_path_id] [int] IDENTITY(1,1) NOT NULL,
[directory_path] [nvarchar](2048) NOT NULL,
[name] [nvarchar](255) NOT NULL,
[file_flag] [bit] NOT NULL,
[filesize] [bigint] NULL,
[create_date] [datetime] NOT NULL
)
Where the full path is actually the combination of directory_path
and name
.
Given the following entries in [dbo].[dir_path]
:
1, '/root/subdir1/subdir2', 'subdir3', 0, NULL, '9/9/2014'
2, '/root/subdir1/subdir2/subdir3', 'somefile.txt', 1, 25, '9/9/2014'
3, '/etc/rc.d', 'rc.local', 1, 10, '9/9/2014'
I need to end up with this in [dbo].[DirTreeEntry]
:
1,'/','/',0,1, NULL,NULL
2,'/root','root',0,0,1,NULL
3,'/root/subdir1','subdir1',0,0,2,NULL
4,'/root/subdir1/subdir2','subdir2',0,0,3,NULL
5,'/root/subdir1/subdir2/subdir3','subdir3',0,0,4,1
6,'/root/subdir1/subdir2/subdir3/somefile.txt','somefile.txt',1,0,5,2
7,'/etc','etc',0,0,1,NULL
8,'/etc/rc.d','rc.d',0,0,7,NULL
9,'/etc/rc.d/rc.local','rc.local',1,0,8,3
The following code from How to create hierarchical structure with list of path? does exactly what I'm looking for as far as building the hierarchy in C#:
public class Node
{
private readonly IDictionary<string, Node> _nodes =
new Dictionary<string, Node>();
public string Path { get; set; }
}
public void AddPath(string path)
{
char[] charSeparators = new char[] {'\\'};
// Parse into a sequence of parts.
string[] parts = path.Split(charSeparators,
StringSplitOptions.RemoveEmptyEntries);
// The current node. Start with this.
Node current = this;
// Iterate through the parts.
foreach (string part in parts)
{
// The child node.
Node child;
// Does the part exist in the current node? If
// not, then add.
if (!current._nodes.TryGetValue(part, out child))
{
// Add the child.
child = new Node {
Path = part
};
// Add to the dictionary.
current._nodes[part] = child;
}
// Set the current to the child.
current = child;
}
}
However, I could be getting source data with 100,000+ entries and I don't want to have to build up that structure in memory on the C# side and then have to send all of that data to SQL. I already have a quick way to get the source data into the database and I'm now in need of a stored procedure to build up the [dbo].[DirTreeEntry]
table based on the source data.
Any guidance would be appreciated!