[blam] Use db4o as storage



commit cc5d6b87bdeac3303dba4100af253eda3cff078d
Author: Carlos MartÃn Nieto <carlos cmartin tk>
Date:   Wed Aug 17 19:41:28 2011 +0200

    Use db4o as storage
    
    Signed-off-by: Carlos MartÃn Nieto <carlos cmartin tk>

 configure.in             |    2 +
 src/Application.cs       |    2 +-
 src/Channel.cs           |   32 +++++-----
 src/ChannelCollection.cs |    2 +-
 src/Defines.cs.in        |    2 +-
 src/ItemList.cs          |    8 ++-
 src/ItemStore.cs         |  138 +++++++++++++++++++++++----------------------
 7 files changed, 97 insertions(+), 89 deletions(-)
---
diff --git a/configure.in b/configure.in
index e31c458..98065ca 100644
--- a/configure.in
+++ b/configure.in
@@ -43,8 +43,10 @@ GTKSHARP_REQUIRED_VERSION=2.8.2
 GNOMESHARP_REQUIRED_VERSION=2.16.1
 GCONF_REQUIRED_VERSION=2.4
 WEBKITSHARP_REQUIRED_VERSION=0.2
+DB4O_REQUIRED_VERSION=7.2
 
 PKG_CHECK_MODULES(BLAM,
+		  db4o >= $DB4O_REQUIRED_VERSION
 		  gtk-sharp-2.0 >= $GTKSHARP_REQUIRED_VERSION
 			webkit-sharp-1.0 >= $WEBKITSHARP_REQUIRED_VERSION
 		  gconf-sharp-2.0 >= $GTKSHARP_REQUIRED_VERSION
diff --git a/src/Application.cs b/src/Application.cs
index 4b52e95..ac21253 100644
--- a/src/Application.cs
+++ b/src/Application.cs
@@ -555,7 +555,7 @@ namespace Imendio.Blam {
             SaveWindowState();
             mainWindow.Hide();
             mCollection.SaveToFile ();
-            ItemStore.Save();
+            ItemStore.Close();
             mCollection.StopAllThreads();
 
             Quit();
diff --git a/src/Channel.cs b/src/Channel.cs
index dee8283..ee01bfc 100644
--- a/src/Channel.cs
+++ b/src/Channel.cs
@@ -42,7 +42,6 @@ namespace Imendio.Blam {
 		[XmlAttribute] public string http_username = "";
 		[XmlAttribute] public string http_password = "";
 
-        ItemStore store = null;
         ArrayList item_list = null;
         Object obj = new Object();
 
@@ -84,7 +83,7 @@ namespace Imendio.Blam {
                 lock(obj){
                     foreach (string id in item_list) {
                         if(id != null){
-                            item = store.Get(id);
+                            item = ItemStore.Get(id);
                             if(item.Unread){
                                 ++unread;
                             }
@@ -105,7 +104,7 @@ namespace Imendio.Blam {
                         if(id == null){ /* TODO: Figure out why this happens */
                             continue;
                         }
-                        item = store.Get(id);
+                        item = ItemStore.Get(id);
                         if(item != null && item.Unread && !item.Old){
                             ++new_items;
                         }
@@ -144,7 +143,6 @@ namespace Imendio.Blam {
         {
             item_list = new ArrayList();
             mIter = new Gtk.TreeIter();
-            store = ItemStore.GetInstance();
         }
 
         public Channel (string name, string url) : this()
@@ -155,7 +153,7 @@ namespace Imendio.Blam {
 
         public Item GetItem (string id)
         {
-            return store.Get(id);
+            return ItemStore.Get(id);
         }
 
         public void Setup()
@@ -166,7 +164,7 @@ namespace Imendio.Blam {
                     if(id == null){
                         continue;
                     }
-                    Item item = store.Get(id);
+                    Item item = ItemStore.Get(id);
                     if(item == null){
                     } else {
                         nlist.Add(id);
@@ -179,10 +177,9 @@ namespace Imendio.Blam {
 
 		public void RemoveItems()
 		{
-			ItemStore store = ItemStore.GetInstance();
 			lock(obj){
 				foreach(string id in item_list){
-					store.Remove(id);
+					ItemStore.Remove(id);
 				}
 			}
 		}
@@ -198,9 +195,10 @@ namespace Imendio.Blam {
                         System.Console.WriteLine("null id {0} on {1}", id, Url);
                         continue;
                     }
-                    item = store.Get(id);
+                    item = ItemStore.Get(id);
                     if (item.Unread) {
                         item.SetUnread (false);
+						ItemStore.Update(item);
                         updated = true;
                         EmitUpdated();
                     }
@@ -246,9 +244,9 @@ namespace Imendio.Blam {
                         continue;
                     }
                     /* We already had it, so just update it */
-                    store.Get(sitem.Id).Update(sitem);
+                    ItemStore.Get(sitem.Id).Update(sitem);
                 } else {
-                    store.Add(new Item(sitem));
+                    ItemStore.Add(new Item(sitem));
                 }
             }
 
@@ -258,7 +256,7 @@ namespace Imendio.Blam {
             lock(obj){
                 foreach(string id in item_list){
                     if(!nitems.Contains(id)){
-                        store.Remove(id);
+                        ItemStore.Remove(id);
                     }
                 }
 
@@ -270,6 +268,7 @@ namespace Imendio.Blam {
 
         public void ItemUpdated(Item item)
         {
+            ItemStore.Update(item);
             EmitUpdated();
         }
 
@@ -280,23 +279,24 @@ namespace Imendio.Blam {
         {
             if(item_list.Contains(item.Id)){
                 /* In this case we only need to update */
-                store.Get(item.Id).Update(item);
+                ItemStore.Get(item.Id).Update(item);
                 return;
             }
 
-            store.Add(item);
+            ItemStore.Add(item);
             lock(obj){
                 item_list.Add(item.Id);
             }
-            store.Get(item.Id).Updated += ItemUpdated;
+            ItemStore.Get(item.Id).Updated += ItemUpdated;
         }
 
         /* Used to cross-mark as read */
         public void MarkItemIdAsRead (string id)
         {
-            Item item = store.Get(id);
+            Item item = ItemStore.Get(id);
             if (item.Unread) {
                 item.Unread = false;
+				ItemStore.Update(item);
                 EmitUpdated();
             }
         }
diff --git a/src/ChannelCollection.cs b/src/ChannelCollection.cs
index 689d103..dfc9f12 100644
--- a/src/ChannelCollection.cs
+++ b/src/ChannelCollection.cs
@@ -341,7 +341,7 @@ namespace Imendio.Blam {
 	private bool WriteTimeoutHandler ()
 	{
 	    SaveToFile ();
-            ItemStore.Save();
+//            ItemStore.Save();
 	    
 	    return false;
 	}
diff --git a/src/Defines.cs.in b/src/Defines.cs.in
index af390ff..9728067 100644
--- a/src/Defines.cs.in
+++ b/src/Defines.cs.in
@@ -17,7 +17,7 @@ namespace Imendio.Blam {
 	public static string APP_DATADIR = DATADIR + "/blam";
 	public static string APP_HOMEDIR = Environment.GetEnvironmentVariable("HOME") + "/.gnome2/blam";
 	public static string APP_COLLECTION_FILE = "collection.xml";
-	public static string APP_ITEMSTORE_FILE = "items.xml";
+	public static string APP_ITEMSTORE_FILE = "items.yap";
 	public static string GNOME_LOCALE_DIR = DATADIR + "/locale";
        
 	public static string THEME_DIR = APP_DATADIR + "/themes";
diff --git a/src/ItemList.cs b/src/ItemList.cs
index 3c9d800..079453f 100644
--- a/src/ItemList.cs
+++ b/src/ItemList.cs
@@ -169,7 +169,6 @@ namespace Imendio.Blam {
 	public void UpdateList ()
 	{
 	    ((ListStore)this.Model).Clear();
-            ItemStore store = ItemStore.GetInstance();
 	    if (this.channel == null) {
 		return;
 	    }
@@ -177,7 +176,7 @@ namespace Imendio.Blam {
                 if(id == null){
                     continue;
                 }
-                (Model as ListStore).AppendValues(store.Get(id));
+                (Model as ListStore).AppendValues(ItemStore.Get(id));
             }
 
 	    GLib.Timeout.Add (100, new GLib.TimeoutHandler (IdleScrollCb));
@@ -229,14 +228,17 @@ namespace Imendio.Blam {
                 lastTimeout = GLib.Timeout.Add(readTimeout, new GLib.TimeoutHandler (SetToRead));
             } else {
                 item.SetUnread(false);
+				ItemStore.Update(item);
             }
 	    }
 	}
 
     private bool SetToRead()
     {
-        if(lastItem == GetSelected())
+        if(lastItem == GetSelected()){
                 lastItem.SetUnread(false);
+				ItemStore.Update(lastItem);
+		}
 
         return false;
     }
diff --git a/src/ItemStore.cs b/src/ItemStore.cs
index e46841c..addb362 100644
--- a/src/ItemStore.cs
+++ b/src/ItemStore.cs
@@ -1,73 +1,109 @@
 using System;
 using System.IO;
-using System.Collections;
+using System.Collections.Generic;
 using System.ServiceModel.Syndication;
 using System.Xml;
 using System.Xml.Serialization;
+using Db4objects.Db4o;
+using Db4objects.Db4o.Query;
 
 namespace Imendio.Blam
 {
     public class ItemStore
     {
-        private Hashtable items;
+		private IObjectContainer db;
+		private System.Collections.Hashtable cache;
         static ItemStore instance = null;
         static string itemfile = Defines.APP_HOMEDIR + "/" + Defines.APP_ITEMSTORE_FILE;
         static string itemfile_tmp = Defines.APP_HOMEDIR + "/" + Defines.APP_ITEMSTORE_FILE + ".tmp";
-        private object db_lock = new object();
+        private static object db_lock = new object();
 
-        public Item Get(string id)
+        public static Item Get(string id)
         {
-            Item item;
-
             if(id == null){
                 Console.Error.WriteLine("Tried to access item with null key");
                 return null;
             }
 
-            lock(db_lock){
-                item = items[id] as Item;
-            }
+			if(instance == null)
+				Load();
+
+			if(instance.cache.ContainsKey(id))
+				return instance.cache[id] as Item;
 
-            return item;
+			IList<Item> items = instance.db.Query<Item>(delegate(Item item) {
+				return item.Id == id;
+			});
+
+			if(items.Count > 1){
+				Console.Error.WriteLine("There is more than one {0} in the DB", id);
+			}
+
+			if(items.Count > 0){
+				instance.cache.Add(id, items[0]);
+				return items[0];
+			} else {
+				return null;
+			}
         }
 
-        public void Add(Item item)
+        public static void Add(Item item)
         {
             if(item.Id == null){
                 Console.Error.WriteLine("Tried to add item with null key");
                 return;
             }
 
-            lock(db_lock){
-                if(items.ContainsKey(item.Id)){
-                    (items[item.Id] as Item).Grab();
-                    return;
-                } else {
-                    item.Grab();
-                    items.Add(item.Id, item);
-                }
-            }
+			if(instance == null)
+				Load();
+
+			IList<Item> items = instance.db.Query<Item>(delegate(Item _item) {
+				return _item.Id == item.Id;
+			});
+
+			if(items.Count > 0)
+				item = items[0];
+
+			/* The DB will overwrite or create a new entry */
+			item.Grab();
+			instance.db.Store(item);
         }
 
-        public void Remove(Item item)
+		public static void Update(Item item)
+		{
+			if(instance == null)
+				Load();
+
+			instance.db.Store(item);
+		}
+        public static void Remove(Item item)
         {
             if(item == null){
+				Console.Error.WriteLine("Tried to store null item");
                 return;
             }
 
-            lock(db_lock){
-                item.Release();
-                if(item.RefCount == 0){
-                    items.Remove(item.Id);
-                }
-            }
+			if(instance == null)
+				Load();
+
+			if(item.RefCount == 1){
+				instance.db.Delete(item);
+			} else {
+				item.Release();
+				instance.db.Store(item);
+			}
         }
 
-        public void Remove(string id)
+        public static void Remove(string id)
         {
-            lock(db_lock){
-                Remove(items[id] as Item);
-            }
+			IList<Item> items = instance.db.Query<Item>(delegate(Item _item) {
+				return _item.Id == id;
+			});
+
+			if(items.Count > 0)
+				Remove(items[0]);
+			else
+				Console.Error.WriteLine("Tried to remove non-existant item {0}", id);
         }
 
         public static ItemStore GetInstance()
@@ -82,49 +118,17 @@ namespace Imendio.Blam
         private static void Load()
         {
             instance = new ItemStore();
-
-            XmlReader reader;
-            try{
-                reader = new XmlTextReader(itemfile);
-            } catch(Exception e){
-                Console.WriteLine("Can't open item db: {0}", e.Message);
-                return;
-            }
-
-            Console.WriteLine("about to format");
-            SyndicationFeed feed = SyndicationFeed.Load(reader);
-            foreach(SyndicationItem item in feed.Items){
-                instance.items.Add(item.Id, new Item(item));
-            }
+			instance.cache = new System.Collections.Hashtable();
+			instance.db = Db4oFactory.OpenFile(Db4oFactory.NewConfiguration(), itemfile);
         }
 
-        public static void Save()
+        public static void Close()
         {
             if(instance == null){
                 return;
             }
 
-            Item[] items;
-
-            lock(instance.db_lock){
-                foreach(Item item in instance.items.Values){
-                    item.WriteExtensions();
-                }
-                items = new Item[instance.items.Count];
-                instance.items.Values.CopyTo(items, 0);
-            }
-            XmlWriter writer = XmlWriter.Create(itemfile_tmp);
-            SyndicationFeed sf = new SyndicationFeed(items);
-            Atom10FeedFormatter fmtr = sf.GetAtom10Formatter();
-            fmtr.WriteTo(writer);
-            writer.Close();
-            File.Delete(itemfile);
-            File.Move(itemfile_tmp, itemfile);
+			instance.db.Close();
         }
-
-       private ItemStore ()
-       {
-            items = new Hashtable();
-       }
     }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]