Saving text index into db file.
[LanSpider.git] / src / LanSpider / Database / Manager.cs
blob87afc73ff9d2bfb4b154318b3b7ed734f3be9500
1 using System;
2 using System.Collections.Generic;
3 using System.Data;
4 using System.Data.SQLite;
5 using System.IO;
7 using LanSpider.Properties;
9 namespace LanSpider.Database
11 public class Manager : IDisposable
13 private const string SelectRootSql = "SELECT node_id FROM node where node_name='root' AND path='root'";
15 private const string SelectRelationshipSql =
16 "SELECT distance FROM relationship WHERE parent_node_id = @parent_node_id AND child_node_id = @child_node_id;";
18 private const string InsertRelationshipSql =
19 "INSERT INTO relationship (parent_node_id,child_node_id,distance, is_leaf) VALUES (@parent_node_id,@child_node_id,@distance,@is_leaf)";
21 private readonly SQLiteConnection _conn;
22 private readonly int _rootId;
24 #region Static methods
26 private static bool SchemaExists( SQLiteConnection connection )
28 SQLiteCommand cmd = new SQLiteCommand( null, connection );
29 cmd.CommandText = "SELECT name FROM sqlite_master WHERE name=@table";
30 cmd.Parameters.Add( new SQLiteParameter( "@table", "node" ) );
31 object tableName = cmd.ExecuteScalar();
33 return tableName != null && tableName != DBNull.Value;
36 private static void CreateSchema( SQLiteConnection connection )
38 SQLiteCommand cmd = new SQLiteCommand( null, connection );
40 cmd.CommandText = Resources.create_db;
41 cmd.ExecuteNonQuery();
44 private static int GerRootNodeId( SQLiteConnection connection )
46 using ( SQLiteCommand cmd = new SQLiteCommand( SelectRootSql, connection ) )
48 return (int) (long) cmd.ExecuteScalar();
52 #endregion Static methods
54 public Manager( string dbFileName )
56 _conn = new SQLiteConnection( String.Format( "Data Source={0};", dbFileName ) );
57 _conn.Open();
59 if ( !SchemaExists( _conn ) )
61 CreateSchema( _conn );
64 _rootId = GerRootNodeId( _conn );
67 public void SavePath( string share, params string[] parts )
69 using ( SQLiteCommand cmd = new SQLiteCommand( _conn ) )
71 int shareId = GetNodeId( share, share );
72 LinkNodes( _rootId, shareId, 1 );
74 string path = share;
75 List<int> parents = new List<int>( parts.Length );
76 parents.Add( shareId );
78 for ( int i = 0; i < parts.Length; ++i )
80 string part = parts[ i ];
81 path += '\\' + part;
82 int partId = GetNodeId( part, path );
84 LinkNodes( _rootId, partId, i + 2, i == parts.Length - 1 );
85 for ( int j = 0; j < parents.Count; ++j )
87 LinkNodes( parents[ j ], partId, i + 1 - j, i==parts.Length-1 );
90 parents.Add( partId );
95 /// <summary>
96 /// Ensure a link between nodes exists.
97 /// </summary>
98 /// <param name="parentId"></param>
99 /// <param name="childId"></param>
100 /// <param name="distance"></param>
101 private void LinkNodes( int parentId, int childId, int distance )
103 LinkNodes( parentId, childId, distance, false );
106 /// <summary>
107 /// Ensure a link between nodes exists.
108 /// </summary>
109 /// <param name="parentId"></param>
110 /// <param name="childId"></param>
111 /// <param name="distance"></param>
112 /// <param name="isLeaf"></param>
113 private void LinkNodes( int parentId, int childId, int distance, bool isLeaf )
115 using ( SQLiteCommand cmd = new SQLiteCommand( _conn ) )
117 cmd.CommandType = CommandType.Text;
118 cmd.CommandText = SelectRelationshipSql;
120 cmd.Parameters.Add( new SQLiteParameter( "@parent_node_id", parentId ) );
121 cmd.Parameters.Add( new SQLiteParameter( "@child_node_id", childId ) );
123 object val = cmd.ExecuteScalar();
125 if ( val == null || val == DBNull.Value )
127 cmd.CommandText = InsertRelationshipSql;
129 cmd.Parameters.Add( new SQLiteParameter( "@distance", distance ) );
130 cmd.Parameters.Add( new SQLiteParameter( "@is_leaf", isLeaf ) );
132 cmd.ExecuteNonQuery();
137 /// <summary>
138 /// Get node id with path precified, create one if not exists.
139 /// </summary>
140 /// <param name="name">node_name</param>
141 /// <param name="path">path</param>
142 /// <returns>Node ID</returns>
143 public int GetNodeId( string name, string path )
145 int nodeId;
147 using ( SQLiteCommand cmd = new SQLiteCommand( _conn ) )
149 cmd.CommandType = CommandType.Text;
151 cmd.CommandText = "SELECT node_id FROM node WHERE path= @path";
152 cmd.Parameters.Add( new SQLiteParameter( "@path", path ) );
154 object val = cmd.ExecuteScalar();
155 if ( val == null || val == DBNull.Value )
157 cmd.CommandText = "INSERT INTO node (node_name, path) VALUES (@node_name, @path)";
158 cmd.Parameters.Add( new SQLiteParameter( "@node_name", name ) );
159 cmd.ExecuteNonQuery();
160 cmd.Parameters.Clear();
162 cmd.CommandText = "SELECT last_insert_rowid()";
163 nodeId = (int) (long) cmd.ExecuteScalar();
165 else
167 nodeId = (int) (long) val;
171 return nodeId;
174 private void SaveRelations( int depth, string path, params string[] parts )
176 if ( depth >= parts.Length - 1 )
178 return;
180 string parentName = parts.GetValue( depth ).ToString();
181 string childName = parts.GetValue( depth + 1 ).ToString();
182 string parentPath = Path.Combine( path, parentName );
184 string childPath = Path.Combine( path, childName );
186 int parentId = GetNodeId( parentName, parentPath );
190 public void Dispose()
192 _conn.Close();