OSDN Git Service

- Gui cleanup - Rework count threads to reduce SQL overhead & improve performance.
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / sql / NotebookTable.java
index fafd2eb..85ce7fb 100644 (file)
@@ -24,9 +24,18 @@ import java.text.DateFormat;
 import java.text.ParseException;\r
 import java.text.SimpleDateFormat;\r
 import java.util.ArrayList;\r
+import java.util.HashMap;\r
 import java.util.List;\r
 \r
+import com.evernote.edam.type.NoteSortOrder;\r
 import com.evernote.edam.type.Notebook;\r
+import com.evernote.edam.type.Publishing;\r
+import com.trolltech.qt.core.QBuffer;\r
+import com.trolltech.qt.core.QByteArray;\r
+import com.trolltech.qt.core.QIODevice;\r
+import com.trolltech.qt.gui.QIcon;\r
+import com.trolltech.qt.gui.QImage;\r
+import com.trolltech.qt.gui.QPixmap;\r
 \r
 import cx.fbn.nevernote.sql.driver.NSqlQuery;\r
 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
@@ -35,18 +44,28 @@ import cx.fbn.nevernote.utilities.Pair;
 public class NotebookTable {\r
        \r
        private final ApplicationLogger                 logger;\r
-       DatabaseConnection                                                      db;\r
+       DatabaseConnection                                              db;\r
+       private final String                                    dbName;\r
+       NSqlQuery                                                               notebookCountQuery;\r
        \r
        // Constructor\r
        public NotebookTable(ApplicationLogger l, DatabaseConnection d) {\r
                logger = l;\r
                db = d;\r
+               dbName = "Notebook";\r
        }\r
+       // Constructor\r
+       public NotebookTable(ApplicationLogger l, DatabaseConnection d, String name) {\r
+               logger = l;\r
+               db = d;\r
+               dbName = name;\r
+       }\r
+\r
        // Create the table\r
-       public void createTable() {\r
+       public void createTable(boolean addDefaulte) {\r
                NSqlQuery query = new NSqlQuery(db.getConnection());\r
-        logger.log(logger.HIGH, "Creating table Notebook...");\r
-        if (!query.exec("Create table Notebook (guid varchar primary key, " +\r
+        logger.log(logger.HIGH, "Creating table "+dbName+"...");\r
+        if (!query.exec("Create table "+dbName+" (guid varchar primary key, " +\r
                        "sequence integer, " +\r
                        "name varchar, "+\r
                        "defaultNotebook varchar, "+\r
@@ -57,34 +76,74 @@ public class NotebookTable {
                        "autoEncrypt boolean, "+\r
                        "local boolean, "+\r
                        "archived boolean)"))                           \r
-               logger.log(logger.HIGH, "Table Notebook creation FAILED!!!");   \r
+               logger.log(logger.HIGH, "Table "+dbName+" creation FAILED!!!");   \r
         Notebook newnote = new Notebook();\r
         newnote.setDefaultNotebook(true);\r
         newnote.setName("My Notebook");\r
         newnote.setPublished(false);\r
         newnote.setGuid("1");\r
-        addNotebook(newnote, true, false);\r
+        \r
+        // Setup an initial notebook\r
+               SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
+        query = new NSqlQuery(db.getConnection());\r
+               query.prepare("Insert Into "+dbName+" (guid, sequence, name, defaultNotebook, "\r
+                               +"serviceCreated, serviceUpdated, published, "   \r
+                               + "isDirty, autoEncrypt, " \r
+                               + "local, archived) Values("\r
+                               +":guid, :sequence, :name, :defaultNotebook,  "\r
+                               +":serviceCreated, :serviceUpdated, :published, "\r
+                               +":isDirty, :autoEncrypt, "\r
+                               +":local, false)");\r
+               query.bindValue(":guid", newnote.getGuid());\r
+               query.bindValue(":sequence", newnote.getUpdateSequenceNum());\r
+               query.bindValue(":name", newnote.getName());\r
+               query.bindValue(":defaultNotebook", newnote.isDefaultNotebook());\r
+               \r
+               StringBuilder serviceCreated = new StringBuilder(simple.format(newnote.getServiceCreated()));                   \r
+               StringBuilder serviceUpdated = new StringBuilder(simple.format(newnote.getServiceUpdated()));\r
+               if (serviceUpdated.toString() == null)\r
+                       serviceUpdated = serviceCreated;\r
+               query.bindValue(":serviceCreated", serviceCreated.toString());\r
+               query.bindValue(":serviceUpdated", serviceCreated.toString());\r
+               query.bindValue(":published",newnote.isPublished());\r
+               \r
+               query.bindValue(":isDirty", true);\r
+               query.bindValue(":autoEncrypt", false);\r
+               query.bindValue(":local", false);\r
+\r
+               boolean check = query.exec();\r
+               if (!check) {\r
+                       logger.log(logger.MEDIUM, "Initial "+dbName+" Table insert failed.");\r
+                       logger.log(logger.MEDIUM, query.lastError().toString());\r
+               }\r
+\r
                \r
        }\r
        // Drop the table\r
        public void dropTable() {\r
                NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               query.exec("Drop table Notebook");\r
+               query.exec("Drop table "+dbName);\r
        }\r
        // Save an individual notebook\r
        public void addNotebook(Notebook tempNotebook, boolean isDirty, boolean local) {\r
+               addNotebook(tempNotebook, isDirty, local, false, false);\r
+       }\r
+       // Save an individual notebook\r
+       public void addNotebook(Notebook tempNotebook, boolean isDirty, boolean local, boolean linked, boolean readOnly) {\r
                boolean check;\r
                \r
                SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               check = query.prepare("Insert Into Notebook (guid, sequence, name, defaultNotebook, "\r
+               check = query.prepare("Insert Into "+dbName+" (guid, sequence, name, defaultNotebook, "\r
                                +"serviceCreated, serviceUpdated, published, "   \r
-                               + "isDirty, autoEncrypt," \r
-                               + "local, archived) Values("\r
+                               + "publishingUri, publishingOrder, publishingAscending, publishingPublicDescription, "\r
+                               + "isDirty, autoEncrypt, stack, " \r
+                               + "local, archived, readOnly, linked) Values("\r
                                +":guid, :sequence, :name, :defaultNotebook,  "\r
                                +":serviceCreated, :serviceUpdated, :published, "\r
+                               +":publishingUri, :publishingOrder, :publishingAscending, :publishingPublicDescription, "\r
                                +":isDirty, :autoEncrypt, "\r
-                               +":local, false)");\r
+                               +":stack, :local, false, :readOnly, :linked)");\r
                query.bindValue(":guid", tempNotebook.getGuid());\r
                query.bindValue(":sequence", tempNotebook.getUpdateSequenceNum());\r
                query.bindValue(":name", tempNotebook.getName());\r
@@ -97,6 +156,21 @@ public class NotebookTable {
                query.bindValue(":serviceCreated", serviceCreated.toString());\r
                query.bindValue(":serviceUpdated", serviceCreated.toString());\r
                query.bindValue(":published",tempNotebook.isPublished());\r
+               query.bindValue(":linked", linked);\r
+               query.bindValue(":readOnly", readOnly);\r
+               \r
+               if (tempNotebook.isPublished() && tempNotebook.getPublishing() != null) {\r
+                       Publishing p = tempNotebook.getPublishing();\r
+                       query.bindValue(":publishingUri", p.getUri());\r
+                       query.bindValue(":publishingOrder", p.getOrder().getValue());\r
+                       query.bindValue(":publishingAscending", p.isAscending());\r
+                       query.bindValue(":publishingPublicDescription", p.getPublicDescription());\r
+               } else {\r
+                       query.bindValue(":publishingUri", "");\r
+                       query.bindValue(":publishingOrder", 1);\r
+                       query.bindValue(":publishingAscending", 1);\r
+                       query.bindValue(":publishingPublicDescription", "");\r
+               }\r
                \r
                if (isDirty)\r
                        query.bindValue(":isDirty", true);\r
@@ -104,10 +178,11 @@ public class NotebookTable {
                        query.bindValue(":isDirty", false);\r
                query.bindValue(":autoEncrypt", false);\r
                query.bindValue(":local", local);\r
+               query.bindValue(":stack", tempNotebook.getStack());\r
 \r
                check = query.exec();\r
                if (!check) {\r
-                       logger.log(logger.MEDIUM, "Notebook Table insert failed.");\r
+                       logger.log(logger.MEDIUM, ""+dbName+" Table insert failed.");\r
                        logger.log(logger.MEDIUM, query.lastError().toString());\r
                }\r
        }\r
@@ -116,21 +191,20 @@ public class NotebookTable {
                boolean check;\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
 \r
-               check = query.prepare("delete from Notebook "\r
-                               +"where guid=:guid");\r
+               check = query.prepare("delete from "+dbName+" where guid=:guid");\r
                if (!check) {\r
-                       logger.log(logger.EXTREME, "Notebook SQL delete prepare has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL delete prepare has failed.");\r
                        logger.log(logger.EXTREME, query.lastError().toString());\r
                }\r
                query.bindValue(":guid", guid);\r
                check = query.exec();\r
                if (!check) \r
-                       logger.log(logger.MEDIUM, "Notebook delete failed.");\r
+                       logger.log(logger.MEDIUM, dbName+" delete failed.");\r
                \r
                // Signal the parent that work needs to be done\r
                if  (needsSync) {\r
                        DeletedTable deletedTable = new DeletedTable(logger, db);\r
-                       deletedTable.addDeletedItem(guid, "Notebook");\r
+                       deletedTable.addDeletedItem(guid, dbName);\r
                }\r
        }\r
        // Update a notebook\r
@@ -140,9 +214,14 @@ public class NotebookTable {
                SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
                \r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               check = query.prepare("Update Notebook set sequence=:sequence, name=:name, defaultNotebook=:defaultNotebook, " +\r
+               check = query.prepare("Update "+dbName+" set sequence=:sequence, name=:name, defaultNotebook=:defaultNotebook, " +\r
                                "serviceCreated=:serviceCreated, serviceUpdated=:serviceUpdated, "+\r
-                               "published=:published, isDirty=:isDirty where guid=:guid ");\r
+                               "published=:published, isDirty=:isDirty, publishinguri=:uri, "+\r
+                               "publishingOrder=:order, " + \r
+                               "publishingAscending=:ascending, " +\r
+                               "publishingPublicDescription=:desc " +\r
+                               "where guid=:guid ");\r
+               \r
                query.bindValue(":sequence", tempNotebook.getUpdateSequenceNum());\r
                query.bindValue(":name", tempNotebook.getName());\r
                query.bindValue(":defaultNotebook", tempNotebook.isDefaultNotebook());\r
@@ -154,11 +233,24 @@ public class NotebookTable {
                \r
                query.bindValue(":published", tempNotebook.isPublished());\r
                query.bindValue(":isDirty", isDirty);\r
+               \r
+               if (tempNotebook.isPublished()) {\r
+                       query.bindValue(":uri", tempNotebook.getPublishing().getUri());\r
+                       query.bindValue(":order", tempNotebook.getPublishing().getOrder().getValue());\r
+                       query.bindValue(":ascending", tempNotebook.getPublishing().isAscending());\r
+                       query.bindValue(":desc", tempNotebook.getPublishing().getPublicDescription());\r
+               } else {\r
+                       query.bindValue(":uri", "");\r
+                       query.bindValue(":order", NoteSortOrder.CREATED.getValue());\r
+                       query.bindValue(":ascending", false);\r
+                       query.bindValue(":desc", "");\r
+               }\r
+               \r
                query.bindValue(":guid", tempNotebook.getGuid());\r
                \r
                check = query.exec();\r
                if (!check) {\r
-                       logger.log(logger.MEDIUM, "Notebook Table update failed.");\r
+                       logger.log(logger.MEDIUM, dbName+" Table update failed.");\r
                        logger.log(logger.MEDIUM, query.lastError().toString());\r
                }\r
        }\r
@@ -173,15 +265,17 @@ public class NotebookTable {
                check = query.exec("Select guid, sequence, name, defaultNotebook, " +\r
                                "serviceCreated, "+\r
                                "serviceUpdated, "+\r
-                               "published, defaultNotebook from Notebook order by name");\r
+                               "published, stack, publishinguri, publishingascending, publishingPublicDescription, "+\r
+                               "publishingOrder from "+dbName+" order by name");\r
                if (!check)\r
-                       logger.log(logger.EXTREME, "Notebook SQL retrieve has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL retrieve has failed.");\r
                while (query.next()) {\r
                        tempNotebook = new Notebook();\r
                        tempNotebook.setGuid(query.valueString(0));\r
                        int sequence = new Integer(query.valueString(1)).intValue();\r
                        tempNotebook.setUpdateSequenceNum(sequence);\r
                        tempNotebook.setName(query.valueString(2));\r
+                       tempNotebook.setDefaultNotebook(query.valueBoolean(3, false));\r
                        DateFormat indfm = null;\r
                        try {\r
                                indfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
@@ -194,7 +288,15 @@ public class NotebookTable {
                                e.printStackTrace();\r
                        }\r
                        tempNotebook.setPublished(new Boolean(query.valueString(6)));\r
-                       tempNotebook.setDefaultNotebook(new Boolean(query.valueString(7)));\r
+                       tempNotebook.setStack(query.valueString(7));\r
+                       if (tempNotebook.isPublished()) {\r
+                               Publishing p = new Publishing();\r
+                               p.setUri(query.valueString(8));\r
+                               p.setAscending(query.valueBoolean(9, false));\r
+                               p.setPublicDescription(query.valueString(10));\r
+                               p.setOrder(NoteSortOrder.findByValue(query.valueInteger(11)));\r
+                               tempNotebook.setPublishing(p);\r
+                       }\r
                        index.add(tempNotebook); \r
                }       \r
                return index;\r
@@ -207,9 +309,9 @@ public class NotebookTable {
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
                                        \r
                check = query.exec("Select guid, sequence, name, defaultNotebook, " +\r
-                               "serviceCreated, serviceUpdated, published from Notebook where local=true order by name");\r
+                               "serviceCreated, serviceUpdated, published, stack from "+dbName+" where local=true order by name");\r
                if (!check)\r
-                       logger.log(logger.EXTREME, "Notebook SQL retrieve has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL retrieve has failed.");\r
                while (query.next()) {\r
                        tempNotebook = new Notebook();\r
                        tempNotebook.setGuid(query.valueString(0));\r
@@ -225,6 +327,7 @@ public class NotebookTable {
                        } catch (ParseException e) {\r
                                e.printStackTrace();\r
                        }\r
+                       tempNotebook.setStack(query.valueString(7));\r
                        index.add(tempNotebook); \r
                }       \r
                return index;\r
@@ -233,9 +336,9 @@ public class NotebookTable {
        public void setArchived(String guid, boolean val) {\r
                boolean check;                  \r
         NSqlQuery query = new NSqlQuery(db.getConnection());                                   \r
-               check = query.prepare("Update notebook set archived=:archived where guid=:guid");\r
+               check = query.prepare("Update "+dbName+" set archived=:archived where guid=:guid");\r
                if (!check)\r
-                       logger.log(logger.EXTREME, "Notebook SQL archive update has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL archive update has failed.");\r
                query.bindValue(":guid", guid);\r
                query.bindValue(":archived", val);\r
                query.exec();\r
@@ -249,9 +352,12 @@ public class NotebookTable {
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
                                        \r
                check = query.exec("Select guid, sequence, name, defaultNotebook, " +\r
-                               "serviceCreated, serviceUpdated, published from Notebook where archived=true order by name");\r
+                               "serviceCreated, serviceUpdated, published, stack, "+\r
+                               "publishinguri, publishingascending, publishingPublicDescription, "+\r
+                               "publishingOrder " +\r
+                               "from "+dbName+" where archived=true order by name");\r
                if (!check)\r
-                       logger.log(logger.EXTREME, "Notebook SQL retrieve has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL retrieve has failed.");\r
                while (query.next()) {\r
                        tempNotebook = new Notebook();\r
                        tempNotebook.setGuid(query.valueString(0));\r
@@ -268,6 +374,17 @@ public class NotebookTable {
                                e.printStackTrace();\r
                        }\r
                        tempNotebook.setPublished(new Boolean(query.valueString(6)));\r
+                       tempNotebook.setStack(query.valueString(7));\r
+                       \r
+                       if (tempNotebook.isPublished()) {\r
+                               Publishing p = new Publishing();\r
+                               p.setUri(query.valueString(8));\r
+                               p.setAscending(query.valueBoolean(9, false));\r
+                               p.setPublicDescription(query.valueString(10));\r
+                               p.setOrder(NoteSortOrder.findByValue(query.valueInteger(11)));\r
+                               tempNotebook.setPublishing(p);\r
+                       }\r
+                       \r
                        index.add(tempNotebook); \r
                }       \r
                return index;\r
@@ -276,7 +393,32 @@ public class NotebookTable {
        public boolean isNotebookLocal(String guid) {\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
                \r
-               query.prepare("Select local from Notebook where guid=:guid");\r
+               query.prepare("Select local from "+dbName+" where guid=:guid");\r
+               query.bindValue(":guid", guid);\r
+               query.exec();\r
+               if (!query.next()) {\r
+                       return false;\r
+               }\r
+               boolean returnValue = query.valueBoolean(0, false);\r
+               return returnValue;\r
+       }\r
+       // Check for a local/remote notebook\r
+       public boolean isNotebookLinked(String guid) {\r
+        NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               query.prepare("Select linked from "+dbName+" where guid=:guid");\r
+               query.bindValue(":guid", guid);\r
+               query.exec();\r
+               if (!query.next()) {\r
+                       return false;\r
+               }\r
+               boolean returnValue = query.valueBoolean(0, false);\r
+               return returnValue;\r
+       }\r
+       public boolean isReadOnly(String guid) {\r
+        NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               query.prepare("Select readOnly from "+dbName+" where guid=:guid and readOnly=true");\r
                query.bindValue(":guid", guid);\r
                query.exec();\r
                if (!query.next()) {\r
@@ -289,23 +431,23 @@ public class NotebookTable {
        public void updateNotebookSequence(String guid, int sequence) {\r
                boolean check;\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               check = query.prepare("Update Notebook set sequence=:sequence where guid=:guid");\r
+               check = query.prepare("Update "+dbName+" set sequence=:sequence where guid=:guid");\r
                query.bindValue(":guid", guid);\r
                query.bindValue(":sequence", sequence);\r
                query.exec();\r
                if (!check) {\r
-                       logger.log(logger.MEDIUM, "Notebook sequence update failed.");\r
+                       logger.log(logger.MEDIUM, dbName+" sequence update failed.");\r
                        logger.log(logger.MEDIUM, query.lastError());\r
                } \r
        }\r
        // Update a notebook GUID number\r
        public void updateNotebookGuid(String oldGuid, String newGuid) {\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               query.prepare("Update Notebook set guid=:newGuid where guid=:oldGuid");\r
+               query.prepare("Update "+dbName+" set guid=:newGuid where guid=:oldGuid");\r
                query.bindValue(":oldGuid", oldGuid);\r
                query.bindValue(":newGuid", newGuid);\r
                if (!query.exec()) {\r
-                       logger.log(logger.MEDIUM, "Notebook guid update failed.");\r
+                       logger.log(logger.MEDIUM, dbName+" guid update failed.");\r
                        logger.log(logger.MEDIUM, query.lastError());\r
                } \r
                \r
@@ -314,7 +456,7 @@ public class NotebookTable {
                query.bindValue(":oldGuid", oldGuid);\r
                query.bindValue(":newGuid", newGuid);\r
                if (!query.exec()) {\r
-                       logger.log(logger.MEDIUM, "Notebook guid update for note failed.");\r
+                       logger.log(logger.MEDIUM, dbName+" guid update for note failed.");\r
                        logger.log(logger.MEDIUM, query.lastError());\r
                } \r
                \r
@@ -326,7 +468,7 @@ public class NotebookTable {
                if (!query.exec()) {\r
                        logger.log(logger.MEDIUM, "Update WatchFolder notebook failed.");\r
                        logger.log(logger.MEDIUM, query.lastError().toString());\r
-               }               \r
+               }\r
        }\r
        // Get a list of notes that need to be updated\r
        public List <Notebook> getDirty() {\r
@@ -334,13 +476,15 @@ public class NotebookTable {
                List<Notebook> index = new ArrayList<Notebook>();\r
                boolean check;\r
                                                \r
-               \r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
                                        \r
                check = query.exec("Select guid, sequence, name, defaultNotebook, " +\r
-                               "serviceCreated, serviceUpdated, published from Notebook where isDirty = true and local=false");\r
+                               "serviceCreated, serviceUpdated, published, stack, "+\r
+                               "publishinguri, publishingascending, publishingPublicDescription, "+\r
+                               "publishingOrder " +\r
+                               "from "+dbName+" where isDirty=true and local=false and linked=false");\r
                if (!check) \r
-                       logger.log(logger.EXTREME, "Notebook SQL retrieve has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL retrieve has failed.");\r
                while (query.next()) {\r
                        tempNotebook = new Notebook();\r
                        tempNotebook.setGuid(query.valueString(0));\r
@@ -349,7 +493,6 @@ public class NotebookTable {
                        tempNotebook.setName(query.valueString(2));\r
                        \r
                        DateFormat indfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
-//                     indfm = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");\r
                        try {\r
                                tempNotebook.setServiceCreated(indfm.parse(query.valueString(4)).getTime());\r
                                tempNotebook.setServiceUpdated(indfm.parse(query.valueString(5)).getTime());\r
@@ -357,7 +500,20 @@ public class NotebookTable {
                                e.printStackTrace();\r
                        }\r
                        tempNotebook.setPublished(new Boolean(query.valueString(6)));\r
-                       index.add(tempNotebook); \r
+                       tempNotebook.setStack(query.valueString(7));\r
+                       \r
+                       if (tempNotebook.isPublished()) {\r
+                               Publishing p = new Publishing();\r
+                               p.setUri(query.valueString(8));\r
+                               p.setAscending(query.valueBoolean(9, false));\r
+                               p.setPublicDescription(query.valueString(10));\r
+                               p.setOrder(NoteSortOrder.findByValue(query.valueInteger(11)));\r
+                               if (p.getPublicDescription().trim().equalsIgnoreCase(""))\r
+                                       p.setPublicDescription(null);\r
+                               tempNotebook.setPublishing(p);\r
+                       }\r
+                       \r
+                       index.add(tempNotebook);\r
                }       \r
                return index;   \r
        }\r
@@ -369,15 +525,23 @@ public class NotebookTable {
                }\r
                updateNotebook(notebook, isDirty);\r
        }\r
+       // This is a convience method to check if a tag exists & update/create based upon it\r
+       public void syncLinkedNotebook(Notebook notebook, boolean isDirty, boolean readOnly) {\r
+               if (!exists(notebook.getGuid())) {\r
+                       addNotebook(notebook, isDirty, false, true, readOnly);\r
+                       return;\r
+               }\r
+               updateNotebook(notebook, isDirty);\r
+       }\r
        // does a record exist?\r
        private boolean exists(String guid) {\r
                \r
                NSqlQuery query = new NSqlQuery(db.getConnection());\r
                \r
-               query.prepare("Select guid from notebook where guid=:guid");\r
+               query.prepare("Select guid from "+dbName+" where guid=:guid");\r
                query.bindValue(":guid", guid);\r
                if (!query.exec())\r
-                       logger.log(logger.EXTREME, "notebook SQL retrieve has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL retrieve has failed.");\r
                boolean retval = query.next();\r
                return retval;\r
        }\r
@@ -385,35 +549,121 @@ public class NotebookTable {
        public void  resetDirtyFlag(String guid) {\r
                NSqlQuery query = new NSqlQuery(db.getConnection());\r
                \r
-               query.prepare("Update notebook set isdirty='false' where guid=:guid");\r
+               query.prepare("Update "+dbName+" set isdirty='false' where guid=:guid");\r
                query.bindValue(":guid", guid);\r
                if (!query.exec())\r
-                       logger.log(logger.EXTREME, "Error resetting notebook dirty field.");\r
+                       logger.log(logger.EXTREME, "Error resetting "+dbName+" dirty field.");\r
        }\r
        // Set the default notebook\r
        public void setDefaultNotebook(String guid) {\r
                NSqlQuery query = new NSqlQuery(db.getConnection());\r
                \r
-               query.prepare("Update notebook set defaultNotebook=false");\r
+               query.prepare("Update "+dbName+" set defaultNotebook=false where linked=false");\r
                if (!query.exec())\r
-                       logger.log(logger.EXTREME, "Error removing default notebook.");\r
-               query.prepare("Update notebook set defaultNotebook=true where guid = :guid");\r
+                       logger.log(logger.EXTREME, "Error removing default "+dbName+".");\r
+               query.prepare("Update "+dbName+" set defaultNotebook=true where guid=:guid where linked=false");\r
                query.bindValue(":guid", guid);\r
                if (!query.exec())\r
-                       logger.log(logger.EXTREME, "Error setting default notebook.");\r
+                       logger.log(logger.EXTREME, "Error setting default "+dbName+".");\r
        }\r
        \r
+       // Get a list of all icons\r
+       public HashMap<String, QIcon> getAllIcons() {\r
+               HashMap<String, QIcon> values = new HashMap<String, QIcon>();\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
        \r
+               if (!query.exec("SELECT guid, icon from "+dbName+" where ARCHIVED  != true"))\r
+                       logger.log(logger.EXTREME, "Error executing "+dbName+" getAllIcons select.");\r
+               while (query.next()) {\r
+                       if (query.getBlob(1) != null) {\r
+                               String guid = query.valueString(0);\r
+                               QByteArray blob = new QByteArray(query.getBlob(1));\r
+                               QIcon icon = new QIcon(QPixmap.fromImage(QImage.fromData(blob)));\r
+                               values.put(guid, icon);\r
+                       }\r
+               }\r
+               return values;\r
+       }\r
+       \r
+       // Get the notebooks custom icon\r
+       public QIcon getIcon(String guid) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               if (!query.prepare("Select icon from "+dbName+" where guid=:guid"))\r
+                       logger.log(logger.EXTREME, "Error preparing "+dbName+" icon select.");\r
+               query.bindValue(":guid", guid);\r
+               if (!query.exec())\r
+                       logger.log(logger.EXTREME, "Error finding "+dbName+" icon.");\r
+               if (!query.next() || query.getBlob(0) == null)\r
+                       return null;\r
+               \r
+               QByteArray blob = new QByteArray(query.getBlob(0));\r
+               QIcon icon = new QIcon(QPixmap.fromImage(QImage.fromData(blob)));\r
+               return icon;\r
+       }\r
+       // Get the notebooks custom icon\r
+       public QByteArray getIconAsByteArray(String guid) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               if (!query.prepare("Select icon from "+dbName+" where guid=:guid"))\r
+                       logger.log(logger.EXTREME, "Error preparing "+dbName+" icon select.");\r
+               query.bindValue(":guid", guid);\r
+               if (!query.exec())\r
+                       logger.log(logger.EXTREME, "Error finding "+dbName+" icon.");\r
+               if (!query.next() || query.getBlob(0) == null)\r
+                       return null;\r
+               \r
+               QByteArray blob = new QByteArray(query.getBlob(0));\r
+               return blob;\r
+       }\r
+       // Set the notebooks custom icon\r
+       public void setIcon(String guid, QIcon icon, String type) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               if (icon == null) {\r
+                       if (!query.prepare("update "+dbName+" set icon=null where guid=:guid"))\r
+                               logger.log(logger.EXTREME, "Error preparing "+dbName+" icon select.");\r
+               } else {\r
+                       if (!query.prepare("update "+dbName+" set icon=:icon where guid=:guid"))\r
+                               logger.log(logger.EXTREME, "Error preparing "+dbName+" icon select.");\r
+                       QBuffer buffer = new QBuffer();\r
+               if (!buffer.open(QIODevice.OpenModeFlag.ReadWrite)) {\r
+                       logger.log(logger.EXTREME, "Failure to open buffer.  Aborting.");\r
+                       return;\r
+               }\r
+               QPixmap p = icon.pixmap(32, 32);\r
+               QImage i = p.toImage();\r
+               i.save(buffer, type.toUpperCase());\r
+               buffer.close();\r
+               QByteArray b = new QByteArray(buffer.buffer());\r
+               if (!b.isNull() && !b.isEmpty())\r
+                       query.bindValue(":icon", b.toByteArray());\r
+               else\r
+                       return;\r
+               }\r
+               query.bindValue(":guid", guid);\r
+               if (!query.exec()) \r
+                       logger.log(logger.LOW, "Error setting "+dbName+" icon. " +query.lastError());\r
+       }\r
+       // Set the notebooks custom icon\r
+       public void setReadOnly(String guid, boolean readOnly) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               if (!query.prepare("update "+dbName+" set readOnly=:readOnly where guid=:guid"))\r
+                       logger.log(logger.EXTREME, "Error preparing "+dbName+" read only.");\r
+               query.bindValue(":guid", guid);\r
+               query.bindValue(":readOnly", readOnly);\r
+               if (!query.exec()) \r
+                       logger.log(logger.LOW, "Error setting "+dbName+" read only. " +query.lastError());\r
+       }\r
 \r
        // does a record exist?\r
        public String findNotebookByName(String newname) {\r
                \r
                NSqlQuery query = new NSqlQuery(db.getConnection());\r
                \r
-               query.prepare("Select guid from notebook where name=:newname");\r
+               query.prepare("Select guid from "+dbName+" where name=:newname");\r
                query.bindValue(":newname", newname);\r
                if (!query.exec())\r
-                       logger.log(logger.EXTREME, "notebook SQL retrieve has failed.");\r
+                       logger.log(logger.EXTREME, dbName+" SQL retrieve has failed.");\r
                String val = null;\r
                if (query.next())\r
                        val = query.valueString(0);\r
@@ -422,20 +672,200 @@ public class NotebookTable {
        // Get a note tag counts\r
        public List<Pair<String,Integer>> getNotebookCounts() {\r
                List<Pair<String,Integer>> counts = new ArrayList<Pair<String,Integer>>();              \r
-               NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               if (!query.exec("select notebookGuid, count(guid) from note where active=1 group by notebookguid;")) {\r
+               if (notebookCountQuery == null) {\r
+                       notebookCountQuery = new NSqlQuery(db.getConnection());\r
+                       notebookCountQuery.prepare("select notebookGuid, count(guid) from note where active=1 group by notebookguid;");\r
+               }\r
+               if (!notebookCountQuery.exec()) {\r
                        logger.log(logger.EXTREME, "NoteTags SQL getTagCounts has failed.");\r
-                       logger.log(logger.MEDIUM, query.lastError());\r
+                       logger.log(logger.MEDIUM, notebookCountQuery.lastError());\r
                        return null;\r
                }\r
-               while (query.next()) {\r
+               while (notebookCountQuery.next()) {\r
                        Pair<String,Integer> newCount = new Pair<String,Integer>();\r
-                       newCount.setFirst(query.valueString(0));\r
-                       newCount.setSecond(query.valueInteger(1));\r
+                       newCount.setFirst(notebookCountQuery.valueString(0));\r
+                       newCount.setSecond(notebookCountQuery.valueInteger(1));\r
                        counts.add(newCount);\r
                }       \r
                return counts;\r
        }\r
 \r
+       // Get/Set stacks\r
+       public void clearStack(String guid) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               query.prepare("Update "+dbName+" set stack='' where guid=:guid");\r
+               query.bindValue(":guid", guid);\r
+               if (!query.exec())\r
+                       logger.log(logger.EXTREME, "Error clearing "+dbName+" stack.");\r
+       }\r
+       // Get/Set stacks\r
+       public void setStack(String guid, String stack) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               query.prepare("Update "+dbName+" set stack=:stack, isDirty=true where guid=:guid");\r
+               query.bindValue(":guid", guid);\r
+               query.bindValue(":stack", stack);\r
+               if (!query.exec())\r
+                       logger.log(logger.EXTREME, "Error setting notebook stack.");\r
+       }\r
+       // Get all stack names\r
+       public List<String> getAllStackNames() {\r
+               List<String> stacks = new ArrayList<String>();\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               if (!query.exec("Select distinct stack from "+dbName)) {\r
+                       logger.log(logger.EXTREME, "Error getting all stack names.");\r
+                       return null;\r
+               }\r
+               \r
+               while (query.next()) {\r
+                       if (query.valueString(0) != null && !query.valueString(0).trim().equals(""))\r
+                               stacks.add(query.valueString(0));\r
+               }\r
+               return stacks;\r
+       }\r
+       // Rename a stack\r
+       public void renameStacks(String oldName, String newName) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               if (!query.prepare("update "+dbName+" set stack=:newName where stack=:oldName")) {\r
+                       logger.log(logger.EXTREME, "Error preparing in renameStacks.");\r
+                       return;\r
+               }\r
+               query.bindValue(":oldName", oldName);\r
+               query.bindValue(":newName", newName);\r
+               if (!query.exec()) {\r
+                       logger.log(logger.EXTREME, "Error updating stack names");\r
+                       return;\r
+               }\r
+               \r
+               if (!query.prepare("update SystemIcon set name=:newName where name=:oldName and type='STACK'")) {\r
+                       logger.log(logger.EXTREME, "Error preparing icon rename in renameStacks.");\r
+                       return;\r
+               }\r
+               query.bindValue(":oldName", oldName);\r
+               query.bindValue(":newName", newName);\r
+               if (!query.exec()) {\r
+                       logger.log(logger.EXTREME, "Error updating stack names for SystemIcon");\r
+                       return;\r
+               }\r
+\r
+       }\r
+       // Get/Set stacks\r
+       public boolean stackExists(String stack) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               query.prepare("Select guid from "+dbName+" where stack=:stack limit 1");\r
+               query.bindValue(":stack", stack);\r
+               if (!query.exec())\r
+                       logger.log(logger.EXTREME, "Error setting "+dbName+" stack.");\r
+               if (query.next())\r
+                       return true;\r
+               else\r
+                       return false;\r
+       }\r
+       // Set Publishing\r
+       public void setPublishing(String guid, boolean published, Publishing p) {\r
+               NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               \r
+               query.prepare("Update "+dbName+" set publishingPublicDescription=:publishingPublicDescription, " +\r
+                               "publishingUri=:publishingUri, publishingOrder=:publishingOrder, published=:published, "+\r
+                               "publishingAscending=:publishingAscending, isdirty=true where "+\r
+                               "guid=:guid");\r
+               query.bindValue(":publishingPublicDescription", p.getPublicDescription());\r
+               query.bindValue(":publishingUri", p.getUri());\r
+                               query.bindValue(":publishingOrder", p.getOrder().getValue());\r
+               query.bindValue(":publishingAscending", p.isAscending());\r
+               query.bindValue(":publishingPublicDescription", p.getPublicDescription());\r
+               query.bindValue(":published", published);\r
+               query.bindValue(":guid", guid);\r
+               if (!query.exec())\r
+                       logger.log(logger.EXTREME, "Error setting "+dbName+" stack.");\r
+       }\r
+       // Get a notebook by uri\r
+       public String getNotebookByUri(String uri) {\r
+               boolean check;\r
+                                       \r
+        NSqlQuery query = new NSqlQuery(db.getConnection());\r
+                                       \r
+               check = query.prepare("Select guid " \r
+                               +"from "+dbName+" where publishingUri=:uri");\r
+               query.bindValue(":uri", uri);\r
+               check = query.exec();\r
+               if (!check)\r
+                       logger.log(logger.EXTREME, "Notebook SQL retrieve guid by uri has failed.");\r
+               if (query.next()) {\r
+                       return query.valueString(0);\r
+               }       \r
+               return null;\r
+       }       \r
+       // Is a notebook a linked notebook?\r
+       public boolean isLinked(String guid) {\r
+               boolean check;\r
+               \r
+        NSqlQuery query = new NSqlQuery(db.getConnection());\r
+                                       \r
+               check = query.prepare("Select guid " \r
+                               +"from "+dbName+" where guid=:guid and linked=true");\r
+               query.bindValue(":guid", guid);\r
+               check = query.exec();\r
+               if (!check)\r
+                       logger.log(logger.EXTREME, "Notebook SQL isLinked failed.");\r
+               if (query.next()) {\r
+                       return true;\r
+               }       \r
+               return false;\r
+       }\r
+\r
+       // Given a notebook, what tags are valid for it?\r
+       public List<String> getValidLinkedTags(String guid) {\r
+               boolean check;\r
+               List<String> tags = new ArrayList<String>();\r
+               \r
+        NSqlQuery query = new NSqlQuery(db.getConnection());                                   \r
+               check = query.prepare("select distinct tagGuid from noteTags " +\r
+                               "where noteGuid in " +\r
+                               "(SELECT guid from note where notebookguid=:guid)");\r
+               query.bindValue(":guid", guid);\r
+               check = query.exec();\r
+               if (!check)\r
+                       logger.log(logger.EXTREME, "Notebook SQL getValidLinedTags failed.");\r
+               while (query.next()) {\r
+                       tags.add(query.valueString(0));\r
+               }       \r
+               return tags;\r
+               \r
+               \r
+       }\r
+       // Given a notebook, what tags are valid for it?\r
+       public void deleteLinkedTags(String guid) {\r
+               \r
+        NSqlQuery query = new NSqlQuery(db.getConnection());                                   \r
+               query.prepare("select distinct tagguid from noteTags " +\r
+                               "where noteGuid in " +\r
+                               "(SELECT guid from note where notebookguid=:guid)");\r
+               query.bindValue(":guid", guid);\r
+               boolean check = query.exec();\r
+               if (!check)\r
+                       logger.log(logger.EXTREME, "Notebook SQL getValidLinedTags failed.");\r
+               while(query.next()) {\r
+                       db.getTagTable().expungeTag(query.valueString(0), false);\r
+               }\r
+               \r
+               \r
+               query.prepare("delete from note " +\r
+                               "where notebookguid=:guid");\r
+               query.bindValue(":guid", guid);\r
+               check = query.exec();\r
+               if (!check)\r
+                       logger.log(logger.EXTREME, "Notebook SQL getValidLinedTags failed.");\r
+\r
+               \r
+               return;\r
+               \r
+               \r
+       }\r
 }\r
 \r