[gnome-games/glchess-vala] Tidy up history code



commit f235a26f97864acdcf562c0bf9d1570841fc3a80
Author: Robert Ancell <robert ancell canonical com>
Date:   Sat Jan 1 13:42:03 2011 +1100

    Tidy up history code

 glchess/src/chess-pgn.vala |    9 +++
 glchess/src/glchess.vala   |    6 +-
 glchess/src/history.vala   |  145 +++++++++++++++++++++++++++++---------------
 3 files changed, 109 insertions(+), 51 deletions(-)
---
diff --git a/glchess/src/chess-pgn.vala b/glchess/src/chess-pgn.vala
index ab6229d..2eb1f7c 100644
--- a/glchess/src/chess-pgn.vala
+++ b/glchess/src/chess-pgn.vala
@@ -30,6 +30,11 @@ private int compare_tag (string name0, string name1)
         return str_index0 - str_index1;
 }
 
+public errordomain PGNError
+{
+    LOAD_ERROR
+}
+
 public class PGNGame
 {
     public HashTable<string, string> tags;
@@ -367,5 +372,9 @@ public class PGN
                 return;
             }
         }
+
+        /* Must have at least one game */
+        if (games == null)
+            throw new PGNError.LOAD_ERROR("No games in PGN file");
     }
 }
\ No newline at end of file
diff --git a/glchess/src/glchess.vala b/glchess/src/glchess.vala
index 27afe6d..3bdb623 100644
--- a/glchess/src/glchess.vala
+++ b/glchess/src/glchess.vala
@@ -243,8 +243,8 @@ public class Application
             var unfinished = history.get_unfinished ();
             if (unfinished != null)
             {
-                var key = unfinished.data;
-                load_game (history.get_game_file (key));
+                var file = unfinished.data;
+                load_game (file);
             }
             else
                 start_game (new ChessGame ());
@@ -1117,7 +1117,7 @@ public class Application
     {
         var pgn = new PGN.from_file (file);
         var pgn_game = pgn.games.nth_data (0);
-        
+
         ChessGame game;
         if (pgn_game.set_up)
         {
diff --git a/glchess/src/history.vala b/glchess/src/history.vala
index d1de781..6c99718 100644
--- a/glchess/src/history.vala
+++ b/glchess/src/history.vala
@@ -1,26 +1,94 @@
 public class History
 {
     private File history_dir;
+    private bool loaded = false;
     private Sqlite.Database db;
 
     public History (File data_dir)
     {
         history_dir = File.new_for_path (Path.build_filename (data_dir.get_path (), "history", null));
+    }
+    
+    public File add (int year, int month, int day, string result) throws Error
+    {
+        load ();
+
+        string relative_path;
+        File file;
+        int version = 0;
+        while (true)
+        {
+            string filename;
+            if (version == 0)
+                filename = "%04d-%02d-%02d.pgn".printf (year, month, day);
+            else
+                filename = "%04d-%02d-%02d-%d.pgn".printf (year, month, day, version);
+            relative_path = Path.build_filename ("%04d".printf (year), "%02d".printf (month), "%02d".printf (day), filename, null);
+
+            file = File.new_for_path (Path.build_filename (history_dir.get_path (), relative_path, null));
+            DirUtils.create_with_parents (Path.get_dirname (file.get_path ()), 0755);
+            try
+            {
+                file.create (FileCreateFlags.NONE);
+                break;
+            }
+            catch (Error e)
+            {
+                if (!(e is IOError.EXISTS))
+                    throw e;
+            }
+
+            version++;
+        }
+
+        Sqlite.Statement statement;
+        assert (db.prepare_v2 ("INSERT INTO GameTable (date, path, result) VALUES (0, \"%s\", \"%s\")".printf (relative_path, result), -1, out statement) == Sqlite.OK);
+        if (statement.step () != Sqlite.DONE)
+            warning ("Failed to insert game into history index: %s", db.errmsg ());
+
+        return file;
+    }
+
+    public List<File> get_unfinished ()
+    {
+        load ();
+
+        List<File> values = null;
+
+        Sqlite.Statement statement;
+        var result = db.prepare_v2 ("SELECT path FROM GameTable WHERE result=\"*\"", -1, out statement);
+        assert (result == Sqlite.OK);
+
+        while ((result = statement.step ()) == Sqlite.ROW)
+        {
+            var path = statement.column_text (0);
+            debug ("%s is unfinished", path);
+            values.append (File.new_for_path (Path.build_filename (history_dir.get_path (), path, null)));
+        }
+
+        if (result != Sqlite.DONE)
+            warning ("Failed to get unfinished games: %s", db.errmsg ());
+
+        return values;
+    }
+
+    private void load ()
+    {
+        if (loaded)
+            return;
 
         var have_history = history_dir.query_exists ();
         DirUtils.create_with_parents (history_dir.get_path (), 0755);
 
         /* Open the database */
-        var result = Sqlite.Database.open_v2 (Path.build_filename (history_dir.get_path (), "index.db"), out db);
-        if (result != Sqlite.OK)
+        if (Sqlite.Database.open_v2 (Path.build_filename (history_dir.get_path (), "index.db"), out db) != Sqlite.OK)
             warning ("Failed to load history index: %s", db.errmsg ());
 
         /* Create table */
         Sqlite.Statement statement;
-        result = db.prepare_v2 ("CREATE TABLE IF NOT EXISTS GameTable (id INTEGER PRIMARY KEY, date INTEGER, path TEXT, fen TEXT, result TEXT)", -1, out statement);
+        var result = db.prepare_v2 ("CREATE TABLE IF NOT EXISTS GameTable (id INTEGER PRIMARY KEY, date INTEGER, path TEXT, fen TEXT, result TEXT)", -1, out statement);
         assert (result == Sqlite.OK);
-        result = statement.step ();
-        if (result != Sqlite.DONE)
+        if (statement.step () != Sqlite.DONE)
             warning ("Failed to create game table: %s", db.errmsg ());
 
         /* Migrate from old settings */
@@ -37,6 +105,8 @@ public class History
                 warning ("Failed to migrate history: %s", e.message);
             }
         }
+
+        loaded = true;
     }
 
     private void load_history_recursive (File base_dir, File dir, bool load_files) throws Error
@@ -52,28 +122,33 @@ public class History
             switch (info.get_file_type ())
             {
             case FileType.REGULAR:
-                if (load_files)
+                if (!load_files)
+                    break;
+
+                var f = File.new_for_path (Path.build_filename (dir.get_path (), info.get_name (), null));
+                debug ("Migrating %s", f.get_path ());
+                    
+                try
                 {
-                    var f = File.new_for_path (Path.build_filename (dir.get_path (), info.get_name (), null));
-                    var relative_path = base_dir.get_relative_path (f);
                     var pgn = new PGN.from_file (f);
                     var game = pgn.games.nth_data (0);
-                    if (game != null)
+
+                    var tokens = game.date.split (".");
+                    int year = 0, month = 0, day = 0;
+                    if (tokens.length == 3)
                     {
-                        /* Copy file */
-                        var new_file = File.new_for_path (Path.build_filename (history_dir.get_path (), relative_path, null));
-                        DirUtils.create_with_parents (Path.get_dirname (new_file.get_path ()), 0755);
-                        f.copy (new_file, FileCopyFlags.NONE);
-
-                        /* Insert into index */
-                        Sqlite.Statement statement;
-                        debug ("  Migrating %s", relative_path);
-                        var result = db.prepare_v2 ("INSERT INTO GameTable (date, path, result) VALUES (0, \"%s\", \"%s\")".printf (relative_path, game.result), -1, out statement);
-                        assert (result == Sqlite.OK);
-                        result = statement.step ();
-                        if (result != Sqlite.DONE)
-                            warning ("Failed to insert game into history index: %s", db.errmsg ());
+                        year = tokens[0].to_int ();
+                        month = tokens[1].to_int ();
+                        day = tokens[2].to_int ();
                     }
+
+                    /* Copy file */
+                    var new_file = add (year, month, day, game.result);
+                    f.copy (new_file, FileCopyFlags.OVERWRITE);
+                }
+                catch (Error e)
+                {
+                    warning ("Failed to migrate file: %s", e.message);
                 }
                 break;
             case FileType.DIRECTORY:
@@ -92,30 +167,4 @@ public class History
             }
         }
     }
-
-    public List<string> get_unfinished ()
-    {
-        List<string> values = null;
-
-        Sqlite.Statement statement;
-        var result = db.prepare_v2 ("SELECT path FROM GameTable WHERE result=\"*\"", -1, out statement);
-        assert (result == Sqlite.OK);
-
-        while ((result = statement.step ()) == Sqlite.ROW)
-        {
-            var path = statement.column_text (0);
-            debug ("%s is unfinished", path);
-            values.append (path);
-        }
-
-        if (result != Sqlite.DONE)
-            warning ("Failed to get unfinished games: %s", db.errmsg ());
-
-        return values;
-    }
-
-    public File get_game_file (string key)
-    {
-        return File.new_for_path (Path.build_filename (history_dir.get_path(), key, null));
-    }
 }



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