Initial separating action-log and sync-log
diff --git a/src/action-log.cc b/src/action-log.cc
index 0111fbb..f49c69e 100644
--- a/src/action-log.cc
+++ b/src/action-log.cc
@@ -20,17 +20,104 @@
  */
 
 #include "action-log.h"
+#include "logging.h"
 
 using namespace boost;
 using namespace std;
 using namespace Ccnx;
 
+INIT_LOGGER ("ActionLog");
+
+const std::string INIT_DATABASE = "\
+CREATE TABLE ActionLog (                                                \n\
+    device_id   INTEGER NOT NULL,                                       \n\
+    seq_no      INTEGER NOT NULL,                                       \n\
+                                                                        \n\
+    action      CHAR(1) NOT NULL, /* 0 for \"update\", 1 for \"delete\". */ \n\
+    filename    TEXT NOT NULL,                                          \n\
+                                                                        \n\
+    version     INTEGER NOT NULL,                                       \n\
+    action_timestamp TIMESTAMP NOT NULL,                                \n\
+                                                                        \n\
+    file_hash   BLOB, /* NULL if action is \"delete\" */                \n\
+    file_atime  TIMESTAMP,                                              \n\
+    file_mtime  TIMESTAMP,                                              \n\
+    file_ctime  TIMESTAMP,                                              \n\
+    file_chmod  INTEGER,                                                \n\
+    file_seg_num INTEGER, /* NULL if action is \"delete\" */            \n\
+                                                                        \n\
+    parent_device_id INTEGER,                                           \n\
+    parent_seq_no    INTEGER,                                           \n\
+                                                                        \n\
+    action_name	     TEXT,                                              \n\
+    action_content_object BLOB,                                         \n\
+                                                                        \n\
+    PRIMARY KEY (device_id, seq_no),                                    \n\
+                                                                        \n\
+    FOREIGN KEY (parent_device_id, parent_seq_no)                       \n\
+	REFERENCES ActionLog (device_id, seq_no)                        \n\
+	ON UPDATE RESTRICT                                              \n\
+	ON DELETE SET NULL                                              \n\
+);                                                                      \n\
+                                                                        \n\
+CREATE INDEX ActionLog_filename_version ON ActionLog (filename,version);        \n\
+CREATE INDEX ActionLog_parent ON ActionLog (parent_device_id, parent_seq_no);   \n\
+CREATE INDEX ActionLog_action_name ON ActionLog (action_name);          \n\
+                                                                        \n\
+CREATE TRIGGER ActionLogInsert_trigger                                  \n\
+    AFTER INSERT ON ActionLog                                           \n\
+    FOR EACH ROW                                                        \n\
+    WHEN (SELECT device_id                                              \n\
+            FROM ActionLog                                              \n\
+            WHERE filename=NEW.filename AND                             \n\
+                  version > NEW.version) IS NULL AND                    \n\
+         (SELECT a.device_id                                            \n\
+            FROM ActionLog a                                            \n\
+                LEFT JOIN SyncNodes s ON s.device_id=a.device_id        \n\
+            WHERE filename=NEW.filename AND                             \n\
+                  version = NEW.version AND                             \n\
+                  a.device_id != NEW.device_id AND                      \n\
+                  s.device_name > (SELECT device_name                   \n\
+                                    FROM SyncNodes                      \n\
+                                    WHERE device_id=NEW.device_id)) IS NULL      \n\
+    BEGIN                                                               \n\
+        SELECT apply_action ((SELECT device_name FROM SyncNodes where device_id=NEW.device_id), \
+                             NEW.device_id, NEW.seq_no,                 \
+                             NEW.action,NEW.filename,NEW.file_hash,     \
+                             strftime('%s', NEW.file_atime),strftime('%s', NEW.file_mtime),strftime('%s', NEW.file_ctime), \
+                             NEW.file_chmod, NEW.file_seg_num); /* function that applies action and adds record the FileState */  \n \
+    END;                                                                \n\
+                                                                        \n\
+CREATE TABLE FileState (                                                \n\
+    type        INTEGER NOT NULL, /* 0 - newest, 1 - oldest */          \n\
+    filename    TEXT NOT NULL,                                          \n\
+    device_id   INTEGER NOT NULL,                                       \n\
+    seq_no      INTEGER NOT NULL,                                       \n\
+    file_hash   BLOB, /* NULL if action is \"delete\" */                \n\
+    file_atime  TIMESTAMP,                                              \n\
+    file_mtime  TIMESTAMP,                                              \n\
+    file_ctime  TIMESTAMP,                                              \n\
+    file_chmod  INTEGER,                                                \n\
+    file_seg_num INTEGER,                                               \n\
+                                                                        \n\
+    PRIMARY KEY (type, filename)                                        \n\
+);                                                                      \n\
+                                                                        \n\
+CREATE INDEX FileState_device_id_seq_no ON FileState (device_id, seq_no); \n\
+";
+
+
 ActionLog::ActionLog (Ccnx::CcnxWrapperPtr ccnx, const boost::filesystem::path &path,
+                      SyncLogPtr syncLog,
                       const std::string &localName, const std::string &sharedFolder)
-  : SyncLog (path, localName)
+  : DbHelper (path)
+  , m_syncLog (syncLog)
   , m_ccnx (ccnx)
   , m_sharedFolderName (sharedFolder)
 {
+  sqlite3_exec (m_db, INIT_DATABASE.c_str (), NULL, NULL, NULL);
+  _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_OK, sqlite3_errmsg (m_db));
+
   int res = sqlite3_create_function (m_db, "apply_action", -1, SQLITE_ANY, reinterpret_cast<void*> (this),
                                  ActionLog::apply_action_xFun,
                                  0, 0);
@@ -89,7 +176,7 @@
 {
   sqlite3_exec (m_db, "BEGIN TRANSACTION;", 0,0,0);
 
-  sqlite3_int64 seq_no = GetNextLocalSeqNo ();
+  sqlite3_int64 seq_no = m_syncLog->GetNextLocalSeqNo ();
   sqlite3_int64 version = 0;
   sqlite3_int64 parent_device_id = -1;
   string        parent_device_name;
@@ -127,7 +214,7 @@
     }
 
 
-  sqlite3_bind_int64 (stmt, 1, m_localDeviceId);
+  sqlite3_bind_int64 (stmt, 1, m_syncLog->GetLocalSyncNodeId ());
   sqlite3_bind_int64 (stmt, 2, seq_no);
   sqlite3_bind_int   (stmt, 3, 0);
   sqlite3_bind_text  (stmt, 4, filename.c_str (), filename.size (), SQLITE_TRANSIENT);
@@ -180,7 +267,7 @@
 
   string item_msg;
   item.SerializeToString (&item_msg);
-  Name actionName = Name (m_localName)("action")(m_sharedFolderName)(seq_no);
+  Name actionName = Name (m_syncLog->GetLocalName ())("action")(m_sharedFolderName)(seq_no);
 
   Bytes actionData = m_ccnx->createContentObject (actionName, item_msg.c_str (), item_msg.size ());
   CcnxCharbufPtr namePtr = actionName.toCcnxCharbuf ();
@@ -222,7 +309,7 @@
       return;
     }
 
-  sqlite3_int64 seq_no = GetNextLocalSeqNo ();
+  sqlite3_int64 seq_no = m_syncLog->GetNextLocalSeqNo ();
 
   sqlite3_stmt *stmt;
   sqlite3_prepare_v2 (m_db, "INSERT INTO ActionLog "
@@ -233,7 +320,7 @@
                       "        ?, ?,"
                       "        ?, ?)", -1, &stmt, 0);
 
-  sqlite3_bind_int64 (stmt, 1, m_localDeviceId);
+  sqlite3_bind_int64 (stmt, 1, m_syncLog->GetLocalSyncNodeId ());
   sqlite3_bind_int64 (stmt, 2, seq_no);
   sqlite3_bind_int   (stmt, 3, 1);
   sqlite3_bind_text  (stmt, 4, filename.c_str (), filename.size (), SQLITE_TRANSIENT);
@@ -254,7 +341,7 @@
 
   string item_msg;
   item.SerializeToString (&item_msg);
-  Name actionName = Name (m_localName)("action")(m_sharedFolderName)(seq_no);
+  Name actionName = Name (m_syncLog->GetLocalName ())("action")(m_sharedFolderName)(seq_no);
 
   Bytes actionData = m_ccnx->createContentObject (actionName, item_msg.c_str (), item_msg.size ());
   CcnxCharbufPtr namePtr = actionName.toCcnxCharbuf ();
diff --git a/src/action-log.h b/src/action-log.h
index 28b221a..33da6d1 100644
--- a/src/action-log.h
+++ b/src/action-log.h
@@ -22,7 +22,9 @@
 #ifndef ACTION_LOG_H
 #define ACTION_LOG_H
 
+#include "db-helper.h"
 #include "sync-log.h"
+
 #include <boost/tuple/tuple.hpp>
 #include <action-item.pb.h>
 #include <ccnx-wrapper.h>
@@ -30,10 +32,11 @@
 class ActionLog;
 typedef boost::shared_ptr<ActionLog> ActionLogPtr;
 
-class ActionLog : public SyncLog
+class ActionLog : public DbHelper
 {
 public:
   ActionLog (Ccnx::CcnxWrapperPtr ccnx, const boost::filesystem::path &path,
+             SyncLogPtr syncLog,
              const std::string &localName, const std::string &sharedFolder);
 
   void
@@ -45,7 +48,7 @@
 
   void
   AddActionMove (const std::string &oldFile, const std::string &newFile);
-  
+
   void
   AddActionDelete (const std::string &filename);
 
@@ -55,8 +58,10 @@
 
   static void
   apply_action_xFun (sqlite3_context *context, int argc, sqlite3_value **argv);
-  
+
 private:
+  SyncLogPtr m_syncLog;
+
   Ccnx::CcnxWrapperPtr m_ccnx;
   Ccnx::Name m_sharedFolderName;
 };
diff --git a/src/db-helper.cc b/src/db-helper.cc
index 82feb89..95ccc7a 100644
--- a/src/db-helper.cc
+++ b/src/db-helper.cc
@@ -20,163 +20,33 @@
  */
 
 #include "db-helper.h"
-// #include "sync-log.h"
+#include "logging.h"
+
 #include <boost/make_shared.hpp>
 #include <boost/ref.hpp>
 #include <boost/throw_exception.hpp>
 
+INIT_LOGGER ("DbHelper");
+
 using namespace boost;
 namespace fs = boost::filesystem;
 
 const std::string INIT_DATABASE = "\
 PRAGMA foreign_keys = ON;                                       \n\
-                                                                \n\
-CREATE TABLE                                                    \n\
-    SyncNodes(                                                  \n\
-        device_id       INTEGER PRIMARY KEY AUTOINCREMENT,      \n\
-        device_name     BLOB NOT NULL,                          \n\
-        description     TEXT,                                   \n\
-        seq_no          INTEGER NOT NULL,                       \n\
-        last_known_locator  BLOB,                               \n\
-        last_update     TIMESTAMP                               \n\
-    );                                                          \n\
-                                                                \n\
-CREATE TRIGGER SyncNodesUpdater_trigger                                \n\
-    BEFORE INSERT ON SyncNodes                                         \n\
-    FOR EACH ROW                                                       \n\
-    WHEN (SELECT device_id                                             \n\
-             FROM SyncNodes                                            \n\
-             WHERE device_name=NEW.device_name)                        \n\
-         IS NOT NULL                                                   \n\
-    BEGIN                                                              \n\
-        UPDATE SyncNodes                                               \n\
-            SET seq_no=max(seq_no,NEW.seq_no)                          \n\
-            WHERE device_name=NEW.device_name;                         \n\
-        SELECT RAISE(IGNORE);                                          \n\
-    END;                                                               \n\
-                                                                       \n\
-CREATE INDEX SyncNodes_device_name ON SyncNodes (device_name);         \n\
-                                                                       \n\
-CREATE TABLE SyncLog(                                                  \n\
-        state_id    INTEGER PRIMARY KEY AUTOINCREMENT,                 \n\
-        state_hash  BLOB NOT NULL UNIQUE,                              \n\
-        last_update TIMESTAMP NOT NULL                                 \n\
-    );                                                                 \n\
-                                                                       \n\
-CREATE TABLE                                                            \n\
-    SyncStateNodes(                                                     \n\
-        id          INTEGER PRIMARY KEY AUTOINCREMENT,                  \n\
-        state_id    INTEGER NOT NULL                                    \n\
-            REFERENCES SyncLog (state_id) ON UPDATE CASCADE ON DELETE CASCADE, \n\
-        device_id   INTEGER NOT NULL                                    \n\
-            REFERENCES SyncNodes (device_id) ON UPDATE CASCADE ON DELETE CASCADE, \n\
-        seq_no      INTEGER NOT NULL                                    \n\
-    );                                                                  \n\
-                                                                        \n\
-CREATE INDEX SyncStateNodes_device_id ON SyncStateNodes (device_id);    \n\
-CREATE INDEX SyncStateNodes_state_id  ON SyncStateNodes (state_id);     \n\
-CREATE INDEX SyncStateNodes_seq_no    ON SyncStateNodes (seq_no);       \n\
-                                                                        \n\
-CREATE TRIGGER SyncLogGuard_trigger                                     \n\
-    BEFORE INSERT ON SyncLog                                            \n\
-    FOR EACH ROW                                                        \n\
-    WHEN (SELECT state_hash                                             \n\
-            FROM SyncLog                                                \n\
-            WHERE state_hash=NEW.state_hash)                            \n\
-        IS NOT NULL                                                     \n\
-    BEGIN                                                               \n\
-        DELETE FROM SyncLog WHERE state_hash=NEW.state_hash;            \n\
-    END;                                                                \n\
-                                                                        \n\
-CREATE TABLE ActionLog (                                                \n\
-    device_id   INTEGER NOT NULL,                                       \n\
-    seq_no      INTEGER NOT NULL,                                       \n\
-                                                                        \n\
-    action      CHAR(1) NOT NULL, /* 0 for \"update\", 1 for \"delete\". */ \n\
-    filename    TEXT NOT NULL,                                          \n\
-                                                                        \n\
-    version     INTEGER NOT NULL,                                       \n\
-    action_timestamp TIMESTAMP NOT NULL,                                \n\
-                                                                        \n\
-    file_hash   BLOB, /* NULL if action is \"delete\" */                \n\
-    file_atime  TIMESTAMP,                                              \n\
-    file_mtime  TIMESTAMP,                                              \n\
-    file_ctime  TIMESTAMP,                                              \n\
-    file_chmod  INTEGER,                                                \n\
-    file_seg_num INTEGER, /* NULL if action is \"delete\" */            \n\
-                                                                        \n\
-    parent_device_id INTEGER,                                           \n\
-    parent_seq_no    INTEGER,                                           \n\
-                                                                        \n\
-    action_name	     TEXT,                                              \n\
-    action_content_object BLOB,                                         \n\
-                                                                        \n\
-    PRIMARY KEY (device_id, seq_no),                                    \n\
-                                                                        \n\
-    FOREIGN KEY (parent_device_id, parent_seq_no)                       \n\
-	REFERENCES ActionLog (device_id, seq_no)                        \n\
-	ON UPDATE RESTRICT                                              \n\
-	ON DELETE SET NULL                                              \n\
-);                                                                      \n\
-                                                                        \n\
-CREATE INDEX ActionLog_filename_version ON ActionLog (filename,version);        \n\
-CREATE INDEX ActionLog_parent ON ActionLog (parent_device_id, parent_seq_no);   \n\
-CREATE INDEX ActionLog_action_name ON ActionLog (action_name);          \n\
-                                                                        \n\
-CREATE TRIGGER ActionLogInsert_trigger                                  \n\
-    AFTER INSERT ON ActionLog                                           \n\
-    FOR EACH ROW                                                        \n\
-    WHEN (SELECT device_id                                              \n\
-            FROM ActionLog                                              \n\
-            WHERE filename=NEW.filename AND                             \n\
-                  version > NEW.version) IS NULL AND                    \n\
-         (SELECT a.device_id                                            \n\
-            FROM ActionLog a                                            \n\
-                LEFT JOIN SyncNodes s ON s.device_id=a.device_id        \n\
-            WHERE filename=NEW.filename AND                             \n\
-                  version = NEW.version AND                             \n\
-                  a.device_id != NEW.device_id AND                      \n\
-                  s.device_name > (SELECT device_name                   \n\
-                                    FROM SyncNodes                      \n\
-                                    WHERE device_id=NEW.device_id)) IS NULL      \n\
-    BEGIN                                                               \n\
-        SELECT apply_action ((SELECT device_name FROM SyncNodes where device_id=NEW.device_id), \
-                             NEW.device_id, NEW.seq_no,                 \
-                             NEW.action,NEW.filename,NEW.file_hash,     \
-                             strftime('%s', NEW.file_atime),strftime('%s', NEW.file_mtime),strftime('%s', NEW.file_ctime), \
-                             NEW.file_chmod, NEW.file_seg_num); /* function that applies action and adds record the FileState */  \n \
-    END;                                                                \n\
-                                                                        \n\
-CREATE TABLE FileState (                                                \n\
-    type        INTEGER NOT NULL, /* 0 - newest, 1 - oldest */          \n\
-    filename    TEXT NOT NULL,                                          \n\
-    device_id   INTEGER NOT NULL,                                       \n\
-    seq_no      INTEGER NOT NULL,                                       \n\
-    file_hash   BLOB, /* NULL if action is \"delete\" */                \n\
-    file_atime  TIMESTAMP,                                              \n\
-    file_mtime  TIMESTAMP,                                              \n\
-    file_ctime  TIMESTAMP,                                              \n\
-    file_chmod  INTEGER,                                                \n\
-    file_seg_num INTEGER,                                               \n\
-                                                                        \n\
-    PRIMARY KEY (type, filename)                                        \n\
-);                                                                      \n\
-                                                                        \n\
-CREATE INDEX FileState_device_id_seq_no ON FileState (device_id, seq_no); \n\
 ";
 
 DbHelper::DbHelper (const fs::path &path)
 {
   fs::path chronoshareDirectory = path / ".chronoshare";
   fs::create_directories (chronoshareDirectory);
-  
+
   int res = sqlite3_open((chronoshareDirectory / "state.db").c_str (), &m_db);
   if (res != SQLITE_OK)
     {
       BOOST_THROW_EXCEPTION (Error::Db ()
                              << errmsg_info_str ("Cannot open/create dabatabase: [" + (chronoshareDirectory / "state.db").string () + "]"));
     }
-  
+
   res = sqlite3_create_function (m_db, "hash", 2, SQLITE_ANY, 0, 0,
                                  DbHelper::hash_xStep, DbHelper::hash_xFinal);
   if (res != SQLITE_OK)
@@ -187,14 +57,8 @@
 
   // Alex: determine if tables initialized. if not, initialize... not sure what is the best way to go...
   // for now, just attempt to create everything
-
-  char *errmsg = 0;
-  res = sqlite3_exec (m_db, INIT_DATABASE.c_str (), NULL, NULL, &errmsg);
-  if (res != SQLITE_OK && errmsg != 0)
-    {
-      std::cerr << "DEBUG: " << errmsg << std::endl;
-      sqlite3_free (errmsg);
-    }
+  sqlite3_exec (m_db, INIT_DATABASE.c_str (), NULL, NULL, NULL);
+  _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_OK, sqlite3_errmsg (m_db));
 }
 
 DbHelper::~DbHelper ()
@@ -222,7 +86,7 @@
       sqlite3_result_error (context, "Hash expects (blob,integer) parameters", -1);
       return;
     }
-  
+
   EVP_MD_CTX **hash_context = reinterpret_cast<EVP_MD_CTX **> (sqlite3_aggregate_context (context, sizeof (EVP_MD_CTX *)));
 
   if (hash_context == 0)
@@ -236,7 +100,7 @@
       *hash_context = EVP_MD_CTX_create ();
       EVP_DigestInit_ex (*hash_context, HASH_FUNCTION (), 0);
     }
-  
+
   int nameBytes       = sqlite3_value_bytes (argv[0]);
   const void *name    = sqlite3_value_blob  (argv[0]);
   sqlite3_int64 seqno = sqlite3_value_int64 (argv[1]);
@@ -262,7 +126,7 @@
       sqlite3_result_blob (context, &charNullResult, 1, SQLITE_TRANSIENT); //SQLITE_TRANSIENT forces to make a copy
       return;
     }
-  
+
   unsigned char *hash = new unsigned char [EVP_MAX_MD_SIZE];
   unsigned int hashLength = 0;
 
@@ -271,7 +135,7 @@
 
   sqlite3_result_blob (context, hash, hashLength, SQLITE_TRANSIENT); //SQLITE_TRANSIENT forces to make a copy
   delete [] hash;
-  
+
   EVP_MD_CTX_destroy (*hash_context);
 }
 
diff --git a/src/sync-core.h b/src/sync-core.h
index 8caefcb..63a0f8e 100644
--- a/src/sync-core.h
+++ b/src/sync-core.h
@@ -15,8 +15,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *	   Zhenkai Zhu <zhenkai@cs.ucla.edu>
- * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
 
 #ifndef SYNC_CORE_H
@@ -32,10 +32,6 @@
 {
 public:
   typedef boost::function<void (const SyncStateMsgPtr & stateMsg) > StateMsgCallback;
-  // typedef map<Name, Name> YellowPage;
-  typedef boost::shared_mutex Mutex;
-  typedef boost::shared_lock<Mutex> ReadLock;
-  typedef boost::unique_lock<Mutex> WriteLock;
 
   static const int FRESHNESS = 2; // seconds
   static const string RECOVER;
@@ -50,7 +46,7 @@
            , const StateMsgCallback &callback   // callback when state change is detected
            , Ccnx::CcnxWrapperPtr ccnx
            , SchedulerPtr scheduler);
-  ~SyncCore();
+  ~SyncCore ();
 
   void
   updateLocalState (sqlite3_int64);
diff --git a/src/sync-log.cc b/src/sync-log.cc
index 6c209f2..5623a83 100644
--- a/src/sync-log.cc
+++ b/src/sync-log.cc
@@ -37,11 +37,73 @@
   cout << q << endl;
 }
 
+const std::string INIT_DATABASE = "\
+CREATE TABLE                                                    \n\
+    SyncNodes(                                                  \n\
+        device_id       INTEGER PRIMARY KEY AUTOINCREMENT,      \n\
+        device_name     BLOB NOT NULL,                          \n\
+        description     TEXT,                                   \n\
+        seq_no          INTEGER NOT NULL,                       \n\
+        last_known_locator  BLOB,                               \n\
+        last_update     TIMESTAMP                               \n\
+    );                                                          \n\
+                                                                \n\
+CREATE TRIGGER SyncNodesUpdater_trigger                                \n\
+    BEFORE INSERT ON SyncNodes                                         \n\
+    FOR EACH ROW                                                       \n\
+    WHEN (SELECT device_id                                             \n\
+             FROM SyncNodes                                            \n\
+             WHERE device_name=NEW.device_name)                        \n\
+         IS NOT NULL                                                   \n\
+    BEGIN                                                              \n\
+        UPDATE SyncNodes                                               \n\
+            SET seq_no=max(seq_no,NEW.seq_no)                          \n\
+            WHERE device_name=NEW.device_name;                         \n\
+        SELECT RAISE(IGNORE);                                          \n\
+    END;                                                               \n\
+                                                                       \n\
+CREATE INDEX SyncNodes_device_name ON SyncNodes (device_name);         \n\
+                                                                       \n\
+CREATE TABLE SyncLog(                                                  \n\
+        state_id    INTEGER PRIMARY KEY AUTOINCREMENT,                 \n\
+        state_hash  BLOB NOT NULL UNIQUE,                              \n\
+        last_update TIMESTAMP NOT NULL                                 \n\
+    );                                                                 \n\
+                                                                       \n\
+CREATE TABLE                                                            \n\
+    SyncStateNodes(                                                     \n\
+        id          INTEGER PRIMARY KEY AUTOINCREMENT,                  \n\
+        state_id    INTEGER NOT NULL                                    \n\
+            REFERENCES SyncLog (state_id) ON UPDATE CASCADE ON DELETE CASCADE, \n\
+        device_id   INTEGER NOT NULL                                    \n\
+            REFERENCES SyncNodes (device_id) ON UPDATE CASCADE ON DELETE CASCADE, \n\
+        seq_no      INTEGER NOT NULL                                    \n\
+    );                                                                  \n\
+                                                                        \n\
+CREATE INDEX SyncStateNodes_device_id ON SyncStateNodes (device_id);    \n\
+CREATE INDEX SyncStateNodes_state_id  ON SyncStateNodes (state_id);     \n\
+CREATE INDEX SyncStateNodes_seq_no    ON SyncStateNodes (seq_no);       \n\
+                                                                        \n\
+CREATE TRIGGER SyncLogGuard_trigger                                     \n\
+    BEFORE INSERT ON SyncLog                                            \n\
+    FOR EACH ROW                                                        \n\
+    WHEN (SELECT state_hash                                             \n\
+            FROM SyncLog                                                \n\
+            WHERE state_hash=NEW.state_hash)                            \n\
+        IS NOT NULL                                                     \n\
+    BEGIN                                                               \n\
+        DELETE FROM SyncLog WHERE state_hash=NEW.state_hash;            \n\
+    END;                                                                \n\
+";
+
 
 SyncLog::SyncLog (const boost::filesystem::path &path, const std::string &localName)
   : DbHelper (path)
   , m_localName (localName)
 {
+  sqlite3_exec (m_db, INIT_DATABASE.c_str (), NULL, NULL, NULL);
+  _LOG_DEBUG_COND (sqlite3_errcode (m_db) != SQLITE_OK, sqlite3_errmsg (m_db));
+
   UpdateDeviceSeqNo (localName, 0);
 
   sqlite3_stmt *stmt;
diff --git a/src/sync-log.h b/src/sync-log.h
index 767a9ff..1ab25e9 100644
--- a/src/sync-log.h
+++ b/src/sync-log.h
@@ -35,13 +35,18 @@
 public:
   SyncLog (const boost::filesystem::path &path, const std::string &localName);
 
-  // // fill in the map with device-name <-> locator pairs
-  // void
-  // initYP(map<Ccnx::Name, Ccnx::Name> &yp);
-
+  /**
+   * @brief Get local username
+   */
   inline const Ccnx::Name &
   GetLocalName () const;
 
+  /**
+   * @brief Get database ID of the local sync node (make sense only for the local database)
+   */
+  inline const sqlite3_int64
+  GetLocalSyncNodeId () const;
+
   sqlite3_int64
   GetNextLocalSeqNo (); // side effect: local seq_no will be increased
 
@@ -111,5 +116,11 @@
   return m_localName;
 }
 
+const sqlite3_int64
+SyncLog::GetLocalSyncNodeId () const
+{
+  return m_localDeviceId;
+}
+
 
 #endif // SYNC_LOG_H