[longomatch/redesign3: 150/156] Refactor DB and add support for automated backups
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch/redesign3: 150/156] Refactor DB and add support for automated backups
- Date: Wed, 17 Aug 2011 22:28:48 +0000 (UTC)
commit 03b043e4ea3d48e9f252f8d99ba33c4dabf5b8e8
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Wed Aug 17 20:37:31 2011 +0200
Refactor DB and add support for automated backups
LongoMatch/Services/DataBase.cs | 402 +++++++++++++++++++++++----------------
1 files changed, 236 insertions(+), 166 deletions(-)
---
diff --git a/LongoMatch/Services/DataBase.cs b/LongoMatch/Services/DataBase.cs
index 1f54d34..9807a62 100644
--- a/LongoMatch/Services/DataBase.cs
+++ b/LongoMatch/Services/DataBase.cs
@@ -20,6 +20,8 @@
using System;
using System.Collections.Generic;
+using System.Linq;
+using System.IO;
using Db4objects.Db4o;
using Db4objects.Db4o.Query;
using Gtk;
@@ -43,15 +45,20 @@ namespace LongoMatch.DB
{
// File path of the database
private string file;
- // Lock object
- private object locker;
private Version dbVersion;
+
+ private BackupDate lastBackup;
- private const int MAYOR=1;
+ private const int MAYOR=2;
private const int MINOR=0;
+
+ private TimeSpan maxDaysWithoutBackup = new TimeSpan(5, 0, 0, 0);
+
+ private const string backupFilename = Constants.DB_FILE + ".backup";
+
/// <summary>
/// Creates a proxy for the database
/// </summary>
@@ -61,40 +68,11 @@ namespace LongoMatch.DB
public DataBase(string file)
{
this.file = file;
- if(!System.IO.File.Exists(file)) {
- // Create new DB and add version
- IObjectContainer db = Db4oFactory.OpenFile(file);
- try {
- dbVersion= new Version(MAYOR,MINOR);
- db.Store(dbVersion);
- }
- finally {
- db.Close();
- }
- }
- else {
- IObjectContainer db = Db4oFactory.OpenFile(file);
- try {
- IQuery query = db.Query();
- query.Constrain(typeof(Version));
- IObjectSet result = query.Execute();
- if(result.HasNext()) {
- dbVersion = (Version)result.Next();
- }
- else {
- dbVersion = new Version(0,0);
- }
- }
- finally
- {
- db.Close();
-
- }
- }
- locker = new object();
+ Init();
+ BackupDB();
}
-
- //// <value>
+
+ /// <value>
/// The database version
/// </value>
public Version Version {
@@ -102,7 +80,20 @@ namespace LongoMatch.DB
return dbVersion;
}
}
-
+
+ /// <summary>
+ /// Initialize the Database
+ /// </summary>
+ public void Init() {
+ /* Create a new DB if it doesn't exists yet */
+ if(!System.IO.File.Exists(file))
+ CreateNewDB();
+
+ GetDBVersion();
+ GetBackupDate();
+ CheckDB();
+ }
+
/// <summary>
/// Retrieve all the projects from the database. This method don't return the
/// the whole <see cref="LongoMatch.DB.Project"/> but the projects fields to
@@ -113,58 +104,56 @@ namespace LongoMatch.DB
/// A <see cref="List"/>
/// </returns>
public List<ProjectDescription> GetAllProjects() {
- lock(this.locker) {
- SetUpdateCascadeOptions();
- List<ProjectDescription> list = new List<ProjectDescription>();
- IObjectContainer db = Db4oFactory.OpenFile(file);
- db.Ext().Configure().ActivationDepth(1);
- try {
- IQuery query = db.Query();
- query.Constrain(typeof(Project));
- IObjectSet result = query.Execute();
- while(result.HasNext()) {
- try {
- Project p = (Project)result.Next();
- ProjectDescription desc = p.Description;
- db.Activate(desc,3);
- try{
- //FIXME: It happens that the project's File object is set to null?Â?Â
- // In that case, reset the value to let the user change it with the
- // projects manager.
- if(desc.File.FilePath == null) {}
- } catch {
- MessagePopup.PopupMessage(null, MessageType.Warning,
- Catalog.GetString("Error retrieving the file " +
- "info for project:")+
- " "+ desc.Title+"\n"+
- Catalog.GetString("This value will be reset. " +
- "Remember to change it later with the " +
- "projects manager"));
- desc.File = new PreviewMediaFile {
- FilePath = Catalog.GetString("Change Me"),
- VideoHeight = 0,
- VideoWidth = 0,
- HasVideo = false,
- HasAudio = false,
- Length = 0,
- Fps = 0,
- VideoCodec = "",
- AudioCodec = "",
- Preview = null,
- };
- db.Store(p);
- }
- list.Add(desc);
+ SetUpdateCascadeOptions();
+ List<ProjectDescription> list = new List<ProjectDescription>();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ db.Ext().Configure().ActivationDepth(1);
+ try {
+ IQuery query = db.Query();
+ query.Constrain(typeof(Project));
+ IObjectSet result = query.Execute();
+ while(result.HasNext()) {
+ try {
+ Project p = (Project)result.Next();
+ ProjectDescription desc = p.Description;
+ db.Activate(desc,3);
+ try{
+ //FIXME: It happens that the project's File object is set to null?Â?Â
+ // In that case, reset the value to let the user change it with the
+ // projects manager.
+ if(desc.File.FilePath == null) {}
} catch {
- Console.WriteLine("Error retreiving project. Skip");
+ MessagePopup.PopupMessage(null, MessageType.Warning,
+ Catalog.GetString("Error retrieving the file " +
+ "info for project:")+
+ " "+ desc.Title+"\n"+
+ Catalog.GetString("This value will be reset. " +
+ "Remember to change it later with the " +
+ "projects manager"));
+ desc.File = new PreviewMediaFile {
+ FilePath = Catalog.GetString("Change Me"),
+ VideoHeight = 0,
+ VideoWidth = 0,
+ HasVideo = false,
+ HasAudio = false,
+ Length = 0,
+ Fps = 0,
+ VideoCodec = "",
+ AudioCodec = "",
+ Preview = null,
+ };
+ db.Store(p);
}
+ list.Add(desc);
+ } catch {
+ Console.WriteLine("Error retreiving project. Skip");
}
- return list;
- }
- finally
- {
- CloseDB(db);
}
+ return list;
+ }
+ finally
+ {
+ CloseDB(db);
}
}
@@ -180,18 +169,16 @@ namespace LongoMatch.DB
/// </returns>
public Project GetProject(String filename) {
Project ret;
- lock(this.locker) {
- IObjectContainer db = Db4oFactory.OpenFile(file);
- try {
- IQuery query = GetQueryWithContrains(db, file);
- IObjectSet result = query.Execute();
- ret = (Project) db.Ext().PeekPersisted(result.Next(),10,true);
- return ret;
- }
- finally
- {
- CloseDB(db);
- }
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try {
+ IQuery query = GetQueryWithContrains(db, file);
+ IObjectSet result = query.Execute();
+ ret = (Project) db.Ext().PeekPersisted(result.Next(),10,true);
+ return ret;
+ }
+ finally
+ {
+ CloseDB(db);
}
}
@@ -202,19 +189,17 @@ namespace LongoMatch.DB
/// A <see cref="Project"/> to add
/// </param>
public void AddProject(Project project) {
- lock(this.locker) {
- IObjectContainer db = Db4oFactory.OpenFile(file);
- try
- {
- if(!Exists(project.Description.File.FilePath,db)) {
- db.Store(project);
- db.Commit();
- }
- else throw new Exception(Catalog.GetString("The Project for this video file already exists.")+"\n"+Catalog.GetString("Try to edit it with the Database Manager"));
- }
- finally {
- CloseDB(db);
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try
+ {
+ if(!Exists(project.Description.File.FilePath,db)) {
+ db.Store(project);
+ db.Commit();
}
+ else throw new Exception(Catalog.GetString("The Project for this video file already exists.")+"\n"+Catalog.GetString("Try to edit it with the Database Manager"));
+ }
+ finally {
+ CloseDB(db);
}
}
@@ -225,20 +210,18 @@ namespace LongoMatch.DB
/// A <see cref="System.String"/> with the project's video file path
/// </param>
public void RemoveProject(string filePath) {
- lock(this.locker) {
- SetDeleteCascadeOptions();
- IObjectContainer db = Db4oFactory.OpenFile(file);
- try {
- IQuery query = GetQueryWithContrains(db, file);
- IObjectSet result = query.Execute();
- Project project = (Project)result.Next();
- db.Delete(project);
- db.Commit();
- }
- finally
- {
- CloseDB(db);
- }
+ SetDeleteCascadeOptions();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try {
+ IQuery query = GetQueryWithContrains(db, file);
+ IObjectSet result = query.Execute();
+ Project project = (Project)result.Next();
+ db.Delete(project);
+ db.Commit();
+ }
+ finally
+ {
+ CloseDB(db);
}
}
@@ -255,35 +238,33 @@ namespace LongoMatch.DB
/// A <see cref="System.String"/> with the old file path
/// </param>
public void UpdateProject(Project project, string previousFileName) {
- lock(this.locker) {
- bool error = false;
- // Configure db4o to cascade on delete for each one of the objects stored in a Project
- SetDeleteCascadeOptions();
- IObjectContainer db = Db4oFactory.OpenFile(file);
- try {
- // We look for a project with the same filename
- if(!Exists(project.Description.File.FilePath,db)) {
- IQuery query = GetQueryWithContrains(db, file);
- IObjectSet result = query.Execute();
- //Get the stored project and replace it with the new one
- if(result.Count == 1) {
- Project fd = (Project)result.Next();
- db.Delete(fd);
- // Add the updated project
- db.Store(project);
- db.Commit();
- } else {
- error = true;
- }
- }
- else
+ bool error = false;
+ // Configure db4o to cascade on delete for each one of the objects stored in a Project
+ SetDeleteCascadeOptions();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try {
+ // We look for a project with the same filename
+ if(!Exists(project.Description.File.FilePath,db)) {
+ IQuery query = GetQueryWithContrains(db, file);
+ IObjectSet result = query.Execute();
+ //Get the stored project and replace it with the new one
+ if(result.Count == 1) {
+ Project fd = (Project)result.Next();
+ db.Delete(fd);
+ // Add the updated project
+ db.Store(project);
+ db.Commit();
+ } else {
error = true;
+ }
}
- finally {
- CloseDB(db);
- if(error)
- throw new Exception();
- }
+ else
+ error = true;
+ }
+ finally {
+ CloseDB(db);
+ if(error)
+ throw new Exception();
}
}
@@ -294,22 +275,20 @@ namespace LongoMatch.DB
/// A <see cref="Project"/> to update
/// </param>
public void UpdateProject(Project project) {
- lock(this.locker) {
- SetDeleteCascadeOptions();
- IObjectContainer db = Db4oFactory.OpenFile(file);
- try {
- IQuery query = GetQueryWithContrains(db, file);
- IObjectSet result = query.Execute();
- //Get the stored project and replace it with the new one
- Project fd = (Project)result.Next();
- db.Delete(fd);
- db.Store(project);
- db.Commit();
- }
- finally
- {
- CloseDB(db);
- }
+ SetDeleteCascadeOptions();
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try {
+ IQuery query = GetQueryWithContrains(db, file);
+ IObjectSet result = query.Execute();
+ //Get the stored project and replace it with the new one
+ Project fd = (Project)result.Next();
+ db.Delete(fd);
+ db.Store(project);
+ db.Commit();
+ }
+ finally
+ {
+ CloseDB(db);
}
}
@@ -332,6 +311,83 @@ namespace LongoMatch.DB
CloseDB(db);
}
}
+
+ private void CreateNewDB () {
+ // Create new DB and add version and last backup date
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try {
+ dbVersion= new Version(MAYOR,MINOR);
+ lastBackup = new BackupDate { Date = DateTime.UtcNow};
+ db.Store(dbVersion);
+ db.Store(lastBackup);
+ }
+ finally {
+ db.Close();
+ }
+ }
+
+ private void GetDBVersion () {
+ dbVersion = GetObject<Version>();
+ if (dbVersion == null)
+ dbVersion = new Version(MAYOR, MINOR);
+ Log.Information("DB version: "+ dbVersion.ToString());
+ }
+
+ private void GetBackupDate () {
+ BackupDate lastBackup = GetObject<BackupDate> ();
+ if (lastBackup == null)
+ lastBackup = new BackupDate {Date = DateTime.UtcNow};
+ Log.Information("Last DB backup: "+ lastBackup.Date.ToShortDateString());
+ }
+
+ private void UpdateBackupDate () {
+ UpdateObject(lastBackup);
+ }
+
+ private T GetObject<T>() {
+ T ret = default(T);
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try {
+ IQuery query = db.Query();
+ query.Constrain(typeof(T));
+ IObjectSet result = query.Execute();
+ if(result.HasNext())
+ ret = (T) result.Next();
+ } finally {
+ db.Close();
+ }
+ return ret;
+ }
+
+ private void UpdateObject<T>(this T element) {
+ IObjectContainer db = Db4oFactory.OpenFile(file);
+ try {
+ IQuery query = db.Query();
+ query.Constrain(typeof(T));
+ IObjectSet result = query.Execute();
+ if(result.HasNext()) {
+ T obj = (T) result.Next();
+ obj = element;
+ db.Store(obj);
+ }
+ } finally {
+ db.Close();
+ }
+ }
+
+ private void CheckDB() {
+ /* FIXME: Check for migrations here */
+ }
+
+ private void BackupDB () {
+ DateTime now = DateTime.UtcNow;
+ if (lastBackup.Date + maxDaysWithoutBackup >= now)
+ return;
+
+ File.Move(file, Path.Combine(MainClass.DBDir(), backupFilename));
+ lastBackup = new BackupDate {Date = now};
+ UpdateBackupDate();
+ }
private IQuery GetQueryWithContrains(IObjectContainer db, string filename) {
IQuery query = db.Query();
@@ -382,5 +438,19 @@ namespace LongoMatch.DB
IObjectSet result = query.Execute();
return (result.HasNext());
}
+
+
+ /* Dummy class to allow having a single instance of BackupDateTime in the DB and make it
+ * easIer to query */
+ protected class BackupDate
+ {
+ public DateTime Date {
+ get;
+ set;
+ }
+ }
+
}
+
+
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]