Beispiel #1
0
        /// <summary>
        /// Given a backup index from the Backup_Indexes database table, provides a list of blocks from the 
        /// Block_Storage table that correspond to that index
        /// </summary>
        /// <param name="index">The index from the Backup_Indexes table</param>
        /// <returns>A list of Block objects; each object corresponds to an entry in the Block_Storage database table</returns>
        public List<Block> GetBlockList(BackupIndex index)
        {
            List<Block> blockList = new List<Block>();
            //Get a list of block foreign keys from the Index_to_Block table
            List<key> keyList = new List<key>();

            string query = "SELECT block_foreign_id,block_foreign_guid FROM Index_to_Block WHERE index_foreign_id = @pIndexID AND index_foreign_guid = @pIndexGUID";
            SQLiteCommand cmd = new SQLiteCommand(query, conn);

            //create a parameter for indexPrimaryKey
            SQLiteParameter pIndexID = new SQLiteParameter("@pIndexID", index.id);
            SQLiteParameter pIndexGUID = new SQLiteParameter("@pIndexGUID", index.sourceGUID);

            cmd.Parameters.Add(pIndexID);
            cmd.Parameters.Add(pIndexGUID);

            try
            {
                //open the connection
                conn.Open();

                using (SQLiteDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        //'reader' iterates through returned
                        //block foreign key records and each is added to list.
                        long blockForeignID = reader.GetInt64(reader.GetOrdinal("block_foreign_id"));
                        string blockForeignGUID = reader.GetString(reader.GetOrdinal("block_foreign_guid"));
                        key currentKey = new key(blockForeignID, blockForeignGUID);
                        keyList.Add(currentKey);
                    }
                }

                //close the connection
                conn.Close();
            }
            catch (SQLiteException ex)
            {
                //if anything is wrong with the sql statement or the database,
                //a SQLiteException will show information about it.
                Debug.Print(ex.Message);

                //always make sure the database connection is closed.
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }

            //For each block_foreign_key, extract the block from the database and add it to the list of Blocks
            foreach (key currentKey in keyList)
            {
                long id = 0;
                string sourceGUID = "";
                string storageGUID = "";
                string storagePath = "";
                long size = 0;
                string dateAndTime = "";

                string blockQuery = "SELECT id,source_guid,storage_guid,storage_path,size,date_created FROM Block_Storage WHERE id = @pBlockForeignID AND source_guid = @pBlockForeignGUID";

                SQLiteCommand blockCmd = new SQLiteCommand(blockQuery, conn);

                SQLiteParameter pBlockForeignID = new SQLiteParameter("@pBlockForeignID", currentKey.id);
                SQLiteParameter pBlockForeignGUID = new SQLiteParameter("@pBlockForeignGUID", currentKey.guid);

                blockCmd.Parameters.Add(pBlockForeignID);
                blockCmd.Parameters.Add(pBlockForeignGUID);

                try
                {
                    conn.Open();

                    using (SQLiteDataReader reader = blockCmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            //'reader' iterates through returned block fields
                            id = reader.GetInt64(reader.GetOrdinal("id"));
                            sourceGUID = reader.GetString(reader.GetOrdinal("source_guid"));
                            storageGUID = reader.GetString(reader.GetOrdinal("storage_guid"));
                            storagePath = reader.GetString(reader.GetOrdinal("storage_path"));
                            size = reader.GetInt64(reader.GetOrdinal("size"));
                            dateAndTime = reader.GetString(reader.GetOrdinal("date_created"));
                        }
                    }

                    conn.Close();
                }
                catch (SQLiteException ex)
                {
                    //if anything is wrong with the sql statement or the database,
                    //a SQLiteException will show information about it.
                    Debug.Print(ex.Message);

                    //always make sure the database connection is closed.
                    if (conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                    }
                }

                Block currentBlock = new Block(sourceGUID, storageGUID, storagePath, size, dateAndTime);
                currentBlock.id = id;
                blockList.Add(currentBlock);
            }

            //sort into ascending order
            blockList.Sort((block1, block2) => block1.id.CompareTo(block2.id));
            return blockList;
        }
Beispiel #2
0
        /// <summary>
        /// Inserts an index into the database.
        /// </summary>
        /// <param name="index">A BackupIndex object to be added to the Backup_Indexes table.</param>
        /// <param name="blocks">A list of Block objects to be added to the Block_Storage table</param>
        public void InsertIndex(BackupIndex index, List<Block> blocks)
        {
            long indexID = 0;
            long indexIDCount = 0;

            // Insert index into Backup_Indexes table
            string backupIndexSql = "INSERT INTO Backup_Indexes (id, source_guid, source_path, first_block_offset, size, date_of_backup, backup_level) VALUES (@pID, @pSourceGUID, @pSourcePath, @pFirstBlockOffset, @pSize, @pDateOfBackup, @pBackupLevel)";
            SQLiteCommand backupIndexCmd = new SQLiteCommand(backupIndexSql, conn);
            //Get ID for index
            //Determine if there are any entries for the given guid
            string indexInitialIDQuery = "SELECT COUNT(id) FROM Backup_Indexes WHERE source_guid = @pSourceGUID";
            SQLiteCommand indexInitialIDCmd = new SQLiteCommand(indexInitialIDQuery, conn);
            //Get previous row ID for given guid
            string indexPreviousIDQuery = "SELECT max(id) FROM Backup_Indexes WHERE source_guid = @pSourceGUID";
            SQLiteCommand indexPreviousIDCmd = new SQLiteCommand(indexPreviousIDQuery, conn);

            //SQLite likes dates and times in a certain format.
            //string currentTimeString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            indexInitialIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
            indexPreviousIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pSourcePath", index.sourcePath));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pFirstBlockOffset", index.firstBlockOffset));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pSize", index.size));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pDateOfBackup", index.dateAndTime));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pBackupLevel", index.backupLevel));

            //open the connection, exectute the query, and close the connection.
            try
            {
                conn.Open();
                indexIDCount = Convert.ToInt64(indexInitialIDCmd.ExecuteScalar());
                if (indexIDCount == 0) // If there are no entries for given guid, then this is the first row
                {
                    indexID = 1;
                }
                else //otherwise get the ID for the previous row and increment
                {
                    indexID = Convert.ToInt64(indexPreviousIDCmd.ExecuteScalar());
                    indexID++;
                }
                backupIndexCmd.Parameters.Add(new SQLiteParameter("@pID", indexID));
                backupIndexCmd.ExecuteNonQuery();
            }
            catch (SQLiteException ex)
            {
                //if anything is wrong with the sql statement or the database,
                //a SQLiteException will show information about it.
                Debug.Print(ex.Message);

                //always make sure the database connection is closed.
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }

            // Go through the array of Blocks and add each to the Block_Storage table; also, for each block add an entry to Index_to_Block table
            foreach (Block currentBlock in blocks)
            {
                long blockID = 0;
                long blockIDCount = 0;

                string blockStorageSql = "INSERT INTO Block_Storage (id, source_guid, storage_guid, storage_path, size, date_created) VALUES (@pID, @pSourceGUID, @pStorageGUID, @pStoragePath, @pSize, @pDateCreated)";
                SQLiteCommand blockStorageCmd = new SQLiteCommand(blockStorageSql, conn);
                //Get ID for block
                //Determine if there are any entries for the given guid
                string blockInitialIDQuery = "SELECT COUNT(block_foreign_id) FROM Index_to_Block WHERE index_foreign_guid = @pSourceGUID";
                SQLiteCommand blockInitialIDCmd = new SQLiteCommand(blockInitialIDQuery, conn);
                //Get previous row ID for given guid
                string blockPreviousIDQuery = "SELECT max(block_foreign_id) FROM Index_to_Block WHERE index_foreign_guid = @pSourceGUID";
                SQLiteCommand blockPreviousIDCmd = new SQLiteCommand(blockPreviousIDQuery, conn);
                // Insert Index_to_Block entry
                string indexToBlockSql = "INSERT INTO Index_to_Block (index_foreign_id, index_foreign_guid, block_foreign_id, block_foreign_guid) VALUES (@pIndexForeignID, @pIndexForeignGUID, @pBlockForeignID, @pBlockForeignGUID)";
                SQLiteCommand indexToBlockCmd = new SQLiteCommand(indexToBlockSql, conn);

                //SQLite likes dates and times in a certain format (ISO-something or other).
                //string currentTimeString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                blockInitialIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
                blockPreviousIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));

                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", currentBlock.sourceGUID));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pStorageGUID", currentBlock.storageGUID));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pStoragePath", currentBlock.storagePath));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pSize", currentBlock.size));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pDateCreated", currentBlock.dateAndTime));

                indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pIndexForeignID", indexID));
                indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pIndexForeignGUID", index.sourceGUID));
                indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pBlockForeignGUID", currentBlock.sourceGUID));

                //open the connection, exectute the query, and close the connection.
                try
                {
                    if (conn.State == ConnectionState.Closed)
                    {
                        conn.Open();
                    }

                    blockIDCount = Convert.ToInt64(blockInitialIDCmd.ExecuteScalar());
                    if (blockIDCount == 0) // If there are no entries for given guid, then this is the first row
                    {
                        blockID = 1;
                    }
                    else //otherwise get the ID for the previous row and increment
                    {
                        blockID = Convert.ToInt64(blockPreviousIDCmd.ExecuteScalar());
                        blockID++;
                    }
                    indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pBlockForeignID", blockID));
                    indexToBlockCmd.ExecuteNonQuery();
                    blockStorageCmd.Parameters.Add(new SQLiteParameter("@pID", blockID));
                    blockStorageCmd.ExecuteNonQuery();
                }
                catch (SQLiteException ex)
                {
                    //if anything is wrong with the sql statement or the database,
                    //a SQLiteException will show information about it.
                    Debug.Print(ex.Message);

                    //always make sure the database connection is closed.
                    if (conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                    }
                }
            }

            if (conn.State == ConnectionState.Open)
            {
                conn.Close();
            }

            IndexDistribution indi = new IndexDistribution();
            indi.sendIndexes();
        }
Beispiel #3
0
        /// <summary>
        /// Given a GUID and backup date/time, provides the corresponding index from the Backup_Indexes database table
        /// </summary>
        /// <param name="sourceGUID">A unique string that identifies a specific source host.</param>
        /// <param name="dateTimeOfBackup">The date/time of the desired backup; also the value in the date_of_backup field of the
        /// Backup_Indexes database table</param>
        /// <returns>A BackupIndex from the Backup_Indexes database table</returns>
        public BackupIndex GetBackupIndex(string sourceGUID, string dateTimeOfBackup)
        {
            string sourcePath = "";
            long firstBlockOffset = 0;
            long size = 0;
            int backupLevel = 0;
            long id = 0;

            string pathQuery = "SELECT source_path FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string offsetQuery = "SELECT first_block_offset FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string sizeQuery = "SELECT size FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string levelQuery = "SELECT backup_level FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string idQuery = "SELECT id FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";

            SQLiteCommand pathCmd = new SQLiteCommand(pathQuery, conn);
            SQLiteCommand offsetCmd = new SQLiteCommand(offsetQuery, conn);
            SQLiteCommand sizeCmd = new SQLiteCommand(sizeQuery, conn);
            SQLiteCommand levelCmd = new SQLiteCommand(levelQuery, conn);
            SQLiteCommand idCmd = new SQLiteCommand(idQuery, conn);

            SQLiteParameter pSourceGUID = new SQLiteParameter("@pSourceGUID", sourceGUID);
            SQLiteParameter pDateOfBackup = new SQLiteParameter("@pDateOfBackup", dateTimeOfBackup);

            pathCmd.Parameters.Add(pSourceGUID);
            pathCmd.Parameters.Add(pDateOfBackup);
            offsetCmd.Parameters.Add(pSourceGUID);
            offsetCmd.Parameters.Add(pDateOfBackup);
            sizeCmd.Parameters.Add(pSourceGUID);
            sizeCmd.Parameters.Add(pDateOfBackup);
            levelCmd.Parameters.Add(pSourceGUID);
            levelCmd.Parameters.Add(pDateOfBackup);
            idCmd.Parameters.Add(pSourceGUID);
            idCmd.Parameters.Add(pDateOfBackup);

            try
            {
                conn.Open();
                sourcePath = pathCmd.ExecuteScalar().ToString();
                firstBlockOffset = Convert.ToInt64(offsetCmd.ExecuteScalar());
                size = Convert.ToInt64(sizeCmd.ExecuteScalar());
                backupLevel = Convert.ToInt16(levelCmd.ExecuteScalar());
                id = Convert.ToInt64(idCmd.ExecuteScalar());
                conn.Close();
            }
            catch (SQLiteException ex)
            {
                //if anything is wrong with the sql statement or the database,
                //a SQLiteException will show information about it.
                Debug.Print(ex.Message);

                //always make sure the database connection is closed.
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }

            BackupIndex index = new BackupIndex(sourceGUID, sourcePath, firstBlockOffset, size, dateTimeOfBackup, backupLevel);
            index.id = id;
            return index;
        }
Beispiel #4
0
        /// <summary>
        /// Given a backup index from the Backup_Indexes database table, provides a list of blocks from the
        /// Block_Storage table that correspond to that index
        /// </summary>
        /// <param name="index">The index from the Backup_Indexes table</param>
        /// <returns>A list of Block objects; each object corresponds to an entry in the Block_Storage database table</returns>
        public List <Block> GetBlockList(BackupIndex index)
        {
            List <Block> blockList = new List <Block>();
            //Get a list of block foreign keys from the Index_to_Block table
            List <key> keyList = new List <key>();

            string        query = "SELECT block_foreign_id,block_foreign_guid FROM Index_to_Block WHERE index_foreign_id = @pIndexID AND index_foreign_guid = @pIndexGUID";
            SQLiteCommand cmd   = new SQLiteCommand(query, conn);

            //create a parameter for indexPrimaryKey
            SQLiteParameter pIndexID   = new SQLiteParameter("@pIndexID", index.id);
            SQLiteParameter pIndexGUID = new SQLiteParameter("@pIndexGUID", index.sourceGUID);

            cmd.Parameters.Add(pIndexID);
            cmd.Parameters.Add(pIndexGUID);

            try
            {
                //open the connection
                conn.Open();

                using (SQLiteDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        //'reader' iterates through returned
                        //block foreign key records and each is added to list.
                        long   blockForeignID   = reader.GetInt64(reader.GetOrdinal("block_foreign_id"));
                        string blockForeignGUID = reader.GetString(reader.GetOrdinal("block_foreign_guid"));
                        key    currentKey       = new key(blockForeignID, blockForeignGUID);
                        keyList.Add(currentKey);
                    }
                }

                //close the connection
                conn.Close();
            }
            catch (SQLiteException ex)
            {
                //if anything is wrong with the sql statement or the database,
                //a SQLiteException will show information about it.
                Debug.Print(ex.Message);

                //always make sure the database connection is closed.
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }

            //For each block_foreign_key, extract the block from the database and add it to the list of Blocks
            foreach (key currentKey in keyList)
            {
                long   id          = 0;
                string sourceGUID  = "";
                string storageGUID = "";
                string storagePath = "";
                long   size        = 0;
                string dateAndTime = "";

                string blockQuery = "SELECT id,source_guid,storage_guid,storage_path,size,date_created FROM Block_Storage WHERE id = @pBlockForeignID AND source_guid = @pBlockForeignGUID";

                SQLiteCommand blockCmd = new SQLiteCommand(blockQuery, conn);

                SQLiteParameter pBlockForeignID   = new SQLiteParameter("@pBlockForeignID", currentKey.id);
                SQLiteParameter pBlockForeignGUID = new SQLiteParameter("@pBlockForeignGUID", currentKey.guid);

                blockCmd.Parameters.Add(pBlockForeignID);
                blockCmd.Parameters.Add(pBlockForeignGUID);

                try
                {
                    conn.Open();

                    using (SQLiteDataReader reader = blockCmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            //'reader' iterates through returned block fields
                            id          = reader.GetInt64(reader.GetOrdinal("id"));
                            sourceGUID  = reader.GetString(reader.GetOrdinal("source_guid"));
                            storageGUID = reader.GetString(reader.GetOrdinal("storage_guid"));
                            storagePath = reader.GetString(reader.GetOrdinal("storage_path"));
                            size        = reader.GetInt64(reader.GetOrdinal("size"));
                            dateAndTime = reader.GetString(reader.GetOrdinal("date_created"));
                        }
                    }

                    conn.Close();
                }
                catch (SQLiteException ex)
                {
                    //if anything is wrong with the sql statement or the database,
                    //a SQLiteException will show information about it.
                    Debug.Print(ex.Message);

                    //always make sure the database connection is closed.
                    if (conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                    }
                }

                Block currentBlock = new Block(sourceGUID, storageGUID, storagePath, size, dateAndTime);
                currentBlock.id = id;
                blockList.Add(currentBlock);
            }

            //sort into ascending order
            blockList.Sort((block1, block2) => block1.id.CompareTo(block2.id));
            return(blockList);
        }
Beispiel #5
0
        /// <summary>
        /// Given a GUID and backup date/time, provides the corresponding index from the Backup_Indexes database table
        /// </summary>
        /// <param name="sourceGUID">A unique string that identifies a specific source host.</param>
        /// <param name="dateTimeOfBackup">The date/time of the desired backup; also the value in the date_of_backup field of the
        /// Backup_Indexes database table</param>
        /// <returns>A BackupIndex from the Backup_Indexes database table</returns>
        public BackupIndex GetBackupIndex(string sourceGUID, string dateTimeOfBackup)
        {
            string sourcePath       = "";
            long   firstBlockOffset = 0;
            long   size             = 0;
            int    backupLevel      = 0;
            long   id = 0;

            string pathQuery   = "SELECT source_path FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string offsetQuery = "SELECT first_block_offset FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string sizeQuery   = "SELECT size FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string levelQuery  = "SELECT backup_level FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";
            string idQuery     = "SELECT id FROM Backup_Indexes WHERE source_guid = @pSourceGUID AND date_of_backup = @pDateOfBackup";

            SQLiteCommand pathCmd   = new SQLiteCommand(pathQuery, conn);
            SQLiteCommand offsetCmd = new SQLiteCommand(offsetQuery, conn);
            SQLiteCommand sizeCmd   = new SQLiteCommand(sizeQuery, conn);
            SQLiteCommand levelCmd  = new SQLiteCommand(levelQuery, conn);
            SQLiteCommand idCmd     = new SQLiteCommand(idQuery, conn);

            SQLiteParameter pSourceGUID   = new SQLiteParameter("@pSourceGUID", sourceGUID);
            SQLiteParameter pDateOfBackup = new SQLiteParameter("@pDateOfBackup", dateTimeOfBackup);

            pathCmd.Parameters.Add(pSourceGUID);
            pathCmd.Parameters.Add(pDateOfBackup);
            offsetCmd.Parameters.Add(pSourceGUID);
            offsetCmd.Parameters.Add(pDateOfBackup);
            sizeCmd.Parameters.Add(pSourceGUID);
            sizeCmd.Parameters.Add(pDateOfBackup);
            levelCmd.Parameters.Add(pSourceGUID);
            levelCmd.Parameters.Add(pDateOfBackup);
            idCmd.Parameters.Add(pSourceGUID);
            idCmd.Parameters.Add(pDateOfBackup);

            try
            {
                conn.Open();
                sourcePath       = pathCmd.ExecuteScalar().ToString();
                firstBlockOffset = Convert.ToInt64(offsetCmd.ExecuteScalar());
                size             = Convert.ToInt64(sizeCmd.ExecuteScalar());
                backupLevel      = Convert.ToInt16(levelCmd.ExecuteScalar());
                id = Convert.ToInt64(idCmd.ExecuteScalar());
                conn.Close();
            }
            catch (SQLiteException ex)
            {
                //if anything is wrong with the sql statement or the database,
                //a SQLiteException will show information about it.
                Debug.Print(ex.Message);

                //always make sure the database connection is closed.
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }

            BackupIndex index = new BackupIndex(sourceGUID, sourcePath, firstBlockOffset, size, dateTimeOfBackup, backupLevel);

            index.id = id;
            return(index);
        }
Beispiel #6
0
        /// <summary>
        /// Inserts an index into the database.
        /// </summary>
        /// <param name="index">A BackupIndex object to be added to the Backup_Indexes table.</param>
        /// <param name="blocks">A list of Block objects to be added to the Block_Storage table</param>
        public void InsertIndex(BackupIndex index, List <Block> blocks)
        {
            long indexID      = 0;
            long indexIDCount = 0;

            // Insert index into Backup_Indexes table
            string        backupIndexSql = "INSERT INTO Backup_Indexes (id, source_guid, source_path, first_block_offset, size, date_of_backup, backup_level) VALUES (@pID, @pSourceGUID, @pSourcePath, @pFirstBlockOffset, @pSize, @pDateOfBackup, @pBackupLevel)";
            SQLiteCommand backupIndexCmd = new SQLiteCommand(backupIndexSql, conn);
            //Get ID for index
            //Determine if there are any entries for the given guid
            string        indexInitialIDQuery = "SELECT COUNT(id) FROM Backup_Indexes WHERE source_guid = @pSourceGUID";
            SQLiteCommand indexInitialIDCmd   = new SQLiteCommand(indexInitialIDQuery, conn);
            //Get previous row ID for given guid
            string        indexPreviousIDQuery = "SELECT max(id) FROM Backup_Indexes WHERE source_guid = @pSourceGUID";
            SQLiteCommand indexPreviousIDCmd   = new SQLiteCommand(indexPreviousIDQuery, conn);

            //SQLite likes dates and times in a certain format.
            //string currentTimeString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            indexInitialIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
            indexPreviousIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pSourcePath", index.sourcePath));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pFirstBlockOffset", index.firstBlockOffset));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pSize", index.size));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pDateOfBackup", index.dateAndTime));
            backupIndexCmd.Parameters.Add(new SQLiteParameter("@pBackupLevel", index.backupLevel));

            //open the connection, exectute the query, and close the connection.
            try
            {
                conn.Open();
                indexIDCount = Convert.ToInt64(indexInitialIDCmd.ExecuteScalar());
                if (indexIDCount == 0) // If there are no entries for given guid, then this is the first row
                {
                    indexID = 1;
                }
                else //otherwise get the ID for the previous row and increment
                {
                    indexID = Convert.ToInt64(indexPreviousIDCmd.ExecuteScalar());
                    indexID++;
                }
                backupIndexCmd.Parameters.Add(new SQLiteParameter("@pID", indexID));
                backupIndexCmd.ExecuteNonQuery();
            }
            catch (SQLiteException ex)
            {
                //if anything is wrong with the sql statement or the database,
                //a SQLiteException will show information about it.
                Debug.Print(ex.Message);

                //always make sure the database connection is closed.
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }

            // Go through the array of Blocks and add each to the Block_Storage table; also, for each block add an entry to Index_to_Block table
            foreach (Block currentBlock in blocks)
            {
                long blockID      = 0;
                long blockIDCount = 0;

                string        blockStorageSql = "INSERT INTO Block_Storage (id, source_guid, storage_guid, storage_path, size, date_created) VALUES (@pID, @pSourceGUID, @pStorageGUID, @pStoragePath, @pSize, @pDateCreated)";
                SQLiteCommand blockStorageCmd = new SQLiteCommand(blockStorageSql, conn);
                //Get ID for block
                //Determine if there are any entries for the given guid
                string        blockInitialIDQuery = "SELECT COUNT(block_foreign_id) FROM Index_to_Block WHERE index_foreign_guid = @pSourceGUID";
                SQLiteCommand blockInitialIDCmd   = new SQLiteCommand(blockInitialIDQuery, conn);
                //Get previous row ID for given guid
                string        blockPreviousIDQuery = "SELECT max(block_foreign_id) FROM Index_to_Block WHERE index_foreign_guid = @pSourceGUID";
                SQLiteCommand blockPreviousIDCmd   = new SQLiteCommand(blockPreviousIDQuery, conn);
                // Insert Index_to_Block entry
                string        indexToBlockSql = "INSERT INTO Index_to_Block (index_foreign_id, index_foreign_guid, block_foreign_id, block_foreign_guid) VALUES (@pIndexForeignID, @pIndexForeignGUID, @pBlockForeignID, @pBlockForeignGUID)";
                SQLiteCommand indexToBlockCmd = new SQLiteCommand(indexToBlockSql, conn);

                //SQLite likes dates and times in a certain format (ISO-something or other).
                //string currentTimeString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                blockInitialIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));
                blockPreviousIDCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", index.sourceGUID));

                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pSourceGUID", currentBlock.sourceGUID));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pStorageGUID", currentBlock.storageGUID));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pStoragePath", currentBlock.storagePath));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pSize", currentBlock.size));
                blockStorageCmd.Parameters.Add(new SQLiteParameter("@pDateCreated", currentBlock.dateAndTime));

                indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pIndexForeignID", indexID));
                indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pIndexForeignGUID", index.sourceGUID));
                indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pBlockForeignGUID", currentBlock.sourceGUID));

                //open the connection, exectute the query, and close the connection.
                try
                {
                    if (conn.State == ConnectionState.Closed)
                    {
                        conn.Open();
                    }

                    blockIDCount = Convert.ToInt64(blockInitialIDCmd.ExecuteScalar());
                    if (blockIDCount == 0) // If there are no entries for given guid, then this is the first row
                    {
                        blockID = 1;
                    }
                    else //otherwise get the ID for the previous row and increment
                    {
                        blockID = Convert.ToInt64(blockPreviousIDCmd.ExecuteScalar());
                        blockID++;
                    }
                    indexToBlockCmd.Parameters.Add(new SQLiteParameter("@pBlockForeignID", blockID));
                    indexToBlockCmd.ExecuteNonQuery();
                    blockStorageCmd.Parameters.Add(new SQLiteParameter("@pID", blockID));
                    blockStorageCmd.ExecuteNonQuery();
                }
                catch (SQLiteException ex)
                {
                    //if anything is wrong with the sql statement or the database,
                    //a SQLiteException will show information about it.
                    Debug.Print(ex.Message);

                    //always make sure the database connection is closed.
                    if (conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                    }
                }
            }

            if (conn.State == ConnectionState.Open)
            {
                conn.Close();
            }

            IndexDistribution indi = new IndexDistribution();

            indi.sendIndexes();
        }
        protected void checkStorageThread()
        {
            if (storageThread.NumChunks() > 0)
            {
                Chunk chunk = storageThread.DequeueChunk();
                Logger.Debug("EchoBackupService:checkStorageThread Finished archiving chunk.");
                //identify host(s) to send to.
                List<GuidAndIP> gai = NetworkFunctions.GetOnlineNodesIPAddresses();
                if (gai.Count < 2)
                {
                    Logger.Warn("EchoBackupService:checkStorageThread not enough online hosts. hosts online: " + gai.Count);
                }
                //send chunk to hosts.
                List<Block> blocks = new List<Block>();
                long filesize = new FileInfo(chunk.Path()).Length;
                for (int i = 0; i < 2 && i < gai.Count; i++)
                {
                    TcpClient tc = new TcpClient(gai[i].ipAddress.ToString(), CommandServer.SERVER_PORT);
                    ClientThread ct = new ClientThread(tc, false, this.guid);
                    PushRequest pr = new PushRequest(Node.GetIPAddress(), this.guid, MiscFunctions.Next());
                    pr.Path = chunk.Path();
                    pr.FileSize = filesize;
                    pr.BackupNumber = chunk.BackupID();
                    pr.ChunkNumber = chunk.ChunkID();
                    ct.EnqueueWork(pr);
                    lock (clientThreads)
                    {
                        clientThreads.Add(ct);
                    }
                    blocks.Add(new Block(this.guid.ToString(), gai[i].guid.ToString(), "bad storage path", filesize, MiscFunctions.DBDateAndTime()));
                }
                //do something with the index so we know about this backup
                //store files in BackupIndex
                IndexDatabase idb = new IndexDatabase();
                foreach (FileInChunk fic in chunk.Files())
                {
                    BackupIndex bi = new BackupIndex();
                    string fullpath = Path.Combine(chunk.BasePath(), fic.path);
                    if (Directory.Exists(fullpath)) continue;
                    bi.backupLevel = 0;
                    bi.dateAndTime = MiscFunctions.DBDateAndTime();
                    bi.firstBlockOffset = 0;
                    bi.size = new FileInfo(fullpath).Length;
                    bi.sourceGUID = this.guid.ToString();
                    bi.sourcePath = fullpath;
                    //todo: we cannot insert multiple blocks for every file. that is what the index-to-block table is for
                    //idb.InsertIndex(bi, blocks);
                }
                //store indexes in DB

            }
            if (storageThread.NumRecoverStructs() > 0)
            {
                RecoverResult rs = storageThread.DequeueRecoverResult();
                lock (recoverResults)
                {
                    recoverResults.Enqueue(rs);
                }
            }
        }