/// <summary> /// Read the config file and populate this class /// </summary> /// <param name="file"> /// A <see cref="System.String"/> /// </param> /// <returns> /// A <see cref="System.Boolean"/> /// </returns> public static bool Init(string file) { if (!Tools.DirectoryExists(TmpDir)) { Log.Warning("Tmpdir doesn't exist"); return false; } FileInfo fi = new FileInfo(file); if (!fi.Exists) { Console.Error.Write("{0} doesn't exist!\n", file); return false; } File = file; MediaTypes = new List<MediaType>(); Previews = new ArrayList(); DatabaseInfo = new DBInfo(); BasePaths = new List<BasePath>(); Directories = new List<MediaDB.Backend.Directory>(); FileIndex = new List<string>(); XmlDocument xdoc = new XmlDocument(); xdoc.Load(File); if (xdoc.FirstChild.Name != "mediadb") { Log.Warning("Malformed config file. Root node name isn't \"mediadb\"!"); return false; } ArrayList basePaths = new ArrayList(); foreach (XmlNode child in xdoc.FirstChild.ChildNodes) { if (child.NodeType != XmlNodeType.Element) continue; switch (child.Name) { case "threads": Threads = Convert.ToInt32(child.FirstChild.Value); break; case "database": foreach (XmlNode c in child.ChildNodes) { if (c.NodeType != XmlNodeType.Element) continue; string v = c.FirstChild.Value; switch (c.Name) { case "host": DatabaseInfo.Host = v; break; case "database": DatabaseInfo.Name = v; break; case "username": DatabaseInfo.Username = v; break; case "password": DatabaseInfo.Password = v; break; } } break; case "mediatypes": foreach (XmlNode c in child.ChildNodes) { if (c.Name == "mediatype") { MediaType mt = new MediaType(); mt.Extension = c.Attributes["extension"].Value.ToString(); mt.Mimetype = c.Attributes["mimetype"].Value.ToString(); MediaTypes.Add(mt); } } break; case "maxbytes": MaxBytes = (1024*1024)*long.Parse(child.FirstChild.Value); break; case "previews": previewQuality = child.Attributes["quality"].Value.ToString(); foreach (XmlNode c in child.ChildNodes) { if (c.Name == "preview") { Preview pv = new Preview(); pv.Name = c.Attributes["name"].Value.ToString(); pv.Width = Convert.ToInt32(c.Attributes["width"].Value); pv.Height = Convert.ToInt32(c.Attributes["height"].Value); if (PreviewMinWidth == 0 || pv.Width < PreviewMinWidth) PreviewMinWidth = pv.Width; if (PreviewMinHeight == 0 || pv.Height < PreviewMinHeight) PreviewMinHeight = pv.Height; Previews.Add(pv); } } break; case "paths": foreach (XmlNode c in child.ChildNodes) { if (c.Name == "path") basePaths.Add(c.FirstChild.Value); } break; } } Previews.Sort(); Previews.Reverse(); dbstr = String.Format("server={0};database={1};userid={2};password={3};", DatabaseInfo.Host, DatabaseInfo.Name, DatabaseInfo.Username, DatabaseInfo.Password); Log.Debug(">>> Connecting to database..."); try { dbcon = new MySqlConnection(dbstr); dbcon.Open(); #if DEBUG DB.Query("TRUNCATE `file`"); DB.Query("TRUNCATE `preview`"); DB.Query("TRUNCATE `keyword`"); DB.Query("TRUNCATE `keyword_rel`"); #endif Log.Debug("OK!\n"); } catch (Exception e) { Log.Debug("FAILED! "); Log.Werror("{0}\n", e.Message); return false; } var db = new DbManager(); // Collect base paths from database if (db.QueryReader("SELECT * FROM base_path")) { while (db.DataReader.Read()) { string p = db.DataReader.GetString("path"); long id = db.DataReader.GetInt64("id"); if (!(basePaths.Contains(p) && Tools.DirectoryExists(p))) { Log.Notice("Base path \"{0}\" is removed from config or file " + "system! Removing from database...\n", p); // NOTE! This uses the global DB object. It's not supposed to // use the local one since it would conflict with the DataReader. DB.Query("DELETE FROM base_path WHERE path = @path", DB.Param("path", p)); } else BasePaths.Add(new BasePath(id, p)); } } // Sync paths from config file with path from database foreach (string path in basePaths) { var t = BasePaths.Find(delegate(BasePath tp) { return tp.Name == path; }); if (t == null) { if (!Tools.DirectoryExists(path)) { Log.Warning("Path \"{0}\" in config file doesn't exits in file " + "system!\n"); } else { Log.Debug("+++ Add {0} to base paths\n", path); long myid; string sql = "INSERT INTO base_path(path) VALUES (@path)"; // NOTE! This uses the global DB object. It's not supposed to // use the local one since it would conflict with the DataReader. if (DB.QueryInsert(out myid, sql, DB.Param("path", path))) BasePaths.Add(new BasePath(myid, path)); else Log.Warning("Failed adding {0} to base_path!\n", path); } } } // Setup the directory list if (db.QueryReader("SELECT * FROM directory")) { while (db.DataReader.Read()) { MediaDB.Backend.Directory d = MediaDB.Backend.Directory.FromSql(db.DataReader); if (Tools.DirectoryExists(d.FullName) && InBasePaths(d.FullName)) { Directories.Add(d); } else { DB.Query("DELETE FROM directory WHERE id='" + d.Id + "'"); } } } // Setup the list of files if (db.QueryReader("SELECT fullname FROM `file`")) { while (db.DataReader.Read()) FileIndex.Add(db.DataReader.GetString("fullname")); } filesCount = FileIndex.Count; db.Dispose(); return true; }
private void SaveKeywords(long Id, string Keywords) { if (Keywords != null) { string[] keys = Keywords.Split(','); foreach (string key in keys) { string lowCaseKey = key.ToLower(); int keyword_id = -1; using (var db = new DbManager(Manager.DbCon)) { string sql = "SELECT id FROM `keywords` WHERE keyword=@keyword"; db.QueryReader(sql, DB.Param("keyword", lowCaseKey)); if (db.DataReader.HasRows) { db.DataReader.Read(); keyword_id = (int)db.DataReader.GetValue(0); } } if (keyword_id == -1) { using (var dbinner = new DbManager(Manager.DbCon)) { long tmpkwdid; string sql = "INSERT INTO keywords (keyword) VALUES (@kwd)"; dbinner.QueryInsert(out tmpkwdid, sql, DB.Param("kwd", lowCaseKey)); keyword_id = (int)tmpkwdid; } } using (var dbinners = new DbManager(Manager.DbCon)) { long tmpid; string sql = "INSERT INTO keyword_rel (file_id,keyword_id) " + "VALUES (@fileid,@keyid)"; dbinners.QueryInsert(out tmpid, sql, DB.Param("fileid", Id), DB.Param("keyid", keyword_id)); } } } }
/// <summary> /// Get media file for <paramref name="fullname"/>. /// If it exists in the database the media file object will be /// populated. Otherwise an empty <see cref="MediaFile"/> object will /// be returned. /// </summary> /// <param name="fullname"></param> /// <returns></returns> public static MediaFile GetMediaFile(string fullname) { if (filesCount == 0) { return null; } MediaFile mf = null; //! TODO: I'm note sure what performance gain this lookup has. One thing //! is certain though: It's a pain keeping it in sync... if (FileIndex.Contains(fullname)) { // This method is called from an async method in Indexer.cs. // So lock during the DB call and release when db done. mutex.WaitOne(); using (var db = new DbManager()) { try { string sql = "SELECT * FROM `file` WHERE fullname = @fn"; // Log.Debug("@@@ GetMEdiaFile({0})\n", sql.Replace("@fn", fullname)); if (db.QueryReader(sql, DB.Param("fn", fullname))) { if (db.DataReader.HasRows) { db.DataReader.Read(); mf = MediaFile.FromSql(db.DataReader); } } } catch (Exception e) { Log.Warning("DB error: {0} {1}\n", e.Message, e.StackTrace); } } // Release the thread mutex.ReleaseMutex(); } return mf; }
/// <summary> /// Populate object from database record /// </summary> /// <param name="reader"> /// A <see cref="MySqlDataReader"/> /// </param> public void SetFromSql(MySqlDataReader reader) { for (int i = 0; i < reader.FieldCount; i++) { switch (reader.GetName(i)) { case "id": Id = reader.GetInt64(i); break; case "name": Name = reader.GetString(i); break; case "fullname": FullName = reader.GetString(i); break; case "sha1_hash": sha1Hash = reader.GetString(i); break; case "directory_id": DirectoryId = reader.GetInt64(i); break; case "mimetype": Mimetype = reader.GetString(i); break; case "title": Title = DB.IsNull(reader[i]) ? null : reader.GetString(i); break; case "description": Description = DB.IsNull(reader[i]) ? null : reader.GetString(i); break; case "copyright": Copyright = DB.IsNull(reader[i]) ? null : reader.GetString(i); break; case "width": Width = reader.GetInt32(i); break; case "height": Height = reader.GetInt32(i); break; case "size": Size = reader.GetInt64(i); break; case "resolution": Resolution = reader.GetDouble(i); break; case "exif": Exif = DB.IsNull(reader[i]) ? null : reader.GetString(i); break; case "created": Created = reader.GetDateTime(i); break; case "modified": if (!DB.IsNull(reader[i])) Modified = reader.GetDateTime(i); break; case "keywords": Keywords = DB.IsNull(reader[i]) ? null : reader.GetString(i); break; } } if (Id > 0) { using (var db = new DbManager(Manager.DbCon)) { var sql = "SELECT * FROM `preview` WHERE file_id=@id"; if (db.QueryReader(sql, DB.Param("id", Id))) { while (db.DataReader.NextResult()) { db.DataReader.Read(); Previews.Add(PreviewFile.FromSql(db.DataReader)); } } } } }