00001
00009 #include "dataholding.h"
00010 #include <boost/bind.hpp>
00011
00012 using namespace Dedupe::Dataholding;
00013
00014 Dataholding::Dataholding( Dedupe::FilePath Path )
00015 : Dataholding::SqliteWrapper( Path.string() )
00016 {
00017 Check( sqlite3_open_v2( Path.string().c_str(), &db_handle,
00018 SQLITE_OPEN_READWRITE |
00019 SQLITE_OPEN_CREATE |
00020 SQLITE_OPEN_FULLMUTEX,
00021 NULL ) );
00022
00023 std::string DatabasePattern;
00024
00025
00026 DatabasePattern =
00027 "CREATE TABLE IF NOT EXISTS StoredFiles (\
00028 Path TEXT NOT NULL,\
00029 Size UNSIGNED BIG INT NOT NULL,\
00030 ChangeDate UNSIGNED BIG INT NOT NULL,\
00031 Type INTEGER NOT NULL,\
00032 Keep BOOLEAN NOT NULL,\
00033 Hash UNSIGNED BIG INT NOT NULL);";
00034 SqlExec( DatabasePattern );
00035 }
00036
00037 bool Dataholding::AlreadyInDatabase( Dedupe::FileInfo const & File )
00038 {
00039 sqlite3_stmt *stmt( NULL );
00040 std::string SqlString(
00041 "SELECT * FROM StoredFiles WHERE Path=? AND Size=? AND ChangeDate=?;");
00042 SqliteWrapper::Check(sqlite3_prepare_v2(
00043 db_handle,
00044 SqlString.c_str(),
00045 SqlString.size(),
00046 &stmt,
00047 NULL ));
00048
00049 sqlite3_bind_text( stmt, 1, File.GetPath().string().c_str(), -1, SQLITE_TRANSIENT);
00050 sqlite3_bind_int64( stmt, 2, File.GetSize());
00051 sqlite3_bind_int64( stmt, 3, File.GetDateChanged());
00052
00053 Dedupe::FileStream ReturningFiles = ExecStatement( stmt );
00054 sqlite3_finalize( stmt );
00055
00056 if( ReturningFiles.size() > 0 ) return true;
00057 else return false;
00058 }
00059
00060 void Dataholding::AddFile( Dedupe::FileInfo const &IncomingFile )
00061 {
00062 sqlite3_stmt *stmt( NULL );
00063 std::string SqlString(
00064 "INSERT INTO StoredFiles( Path, Size, ChangeDate, Type, Keep, Hash) VALUES (?,?,?,?,?,?)");
00065 SqliteWrapper::Check(sqlite3_prepare_v2(
00066 db_handle,
00067 SqlString.c_str(),
00068 SqlString.size(),
00069 &stmt,
00070 NULL ));
00071
00072 sqlite3_bind_text( stmt, 1, IncomingFile.GetPath().string().c_str(), -1, SQLITE_TRANSIENT);
00073 sqlite3_bind_int64( stmt, 2, IncomingFile.GetSize());
00074 sqlite3_bind_int64( stmt, 3, IncomingFile.GetDateChanged());
00075 sqlite3_bind_int( stmt, 4, IncomingFile.GetType());
00076 sqlite3_bind_int( stmt, 5, IncomingFile.GetKeep());
00077 sqlite3_bind_int64( stmt, 6, IncomingFile.GetHash());
00078
00079 ExecStatement( stmt );
00080
00081 sqlite3_finalize( stmt );
00082
00083 }
00084
00085 void Dataholding::AddFiles( Dedupe::FileStream const &IncomingFiles )
00086 {
00087 std::for_each(
00088 IncomingFiles.begin(),
00089 IncomingFiles.end(),
00090 boost::bind( &Dataholding::AddFile, this, _1 ));
00091 }
00092
00093 void Dataholding::UpdateFile( Dedupe::FileInfo const &Updated )
00094 {
00095 sqlite3_stmt *stmt( NULL );
00096 std::string SqlString(
00097 "UPDATE StoredFiles SET Size=?, ChangeDate=?, Type=?, Keep=?, Hash=? WHERE Path=?");
00098 SqliteWrapper::Check(sqlite3_prepare_v2(
00099 db_handle,
00100 SqlString.c_str(),
00101 SqlString.size(),
00102 &stmt,
00103 NULL ));
00104
00105
00106 sqlite3_bind_int64( stmt, 1, Updated.GetSize());
00107 sqlite3_bind_int64( stmt, 2, Updated.GetDateChanged());
00108 sqlite3_bind_int( stmt, 3, Updated.GetType());
00109 sqlite3_bind_int( stmt, 4, Updated.GetKeep());
00110 sqlite3_bind_int64( stmt, 5, Updated.GetHash());
00111 sqlite3_bind_text( stmt, 6, Updated.GetPath().string().c_str(), -1, SQLITE_TRANSIENT);
00112
00113 ExecStatement( stmt );
00114
00115 sqlite3_finalize( stmt );
00116 }
00117
00118 void Dataholding::DelFile( Dedupe::FileInfo const &FileToDel )
00119 {
00120 sqlite3_stmt *stmt( NULL );
00121 std::string SqlString(
00122 "DELETE FROM StoredFiles WHERE Path=?;");
00123 SqliteWrapper::Check(sqlite3_prepare_v2(
00124 db_handle,
00125 SqlString.c_str(),
00126 SqlString.size(),
00127 &stmt,
00128 NULL ));
00129
00130 sqlite3_bind_text( stmt, 1, FileToDel.GetPath().string().c_str(), -1, SQLITE_TRANSIENT);
00131
00132 ExecStatement( stmt );
00133
00134 sqlite3_finalize( stmt );
00135 }
00136
00137 void Dataholding::DelFiles( Dedupe::FileStream const &FilesToDel )
00138 {
00139 std::for_each(
00140 FilesToDel.begin(),
00141 FilesToDel.end(),
00142 boost::bind( &Dataholding::DelFile, this, _1 ));
00143 }
00144
00145 Dedupe::FileStream Dataholding::GetFiles()
00146 {
00147
00148 return SqlExec( "SELECT * FROM StoredFiles;" );
00149
00150 }
00151
00152 Dedupe::FileStream Dataholding::ExecStatement( sqlite3_stmt *stmt )
00153 {
00154 Dedupe::FileStream ReturningInfos;
00155 Dedupe::FilePath Path( "" );
00156 unsigned long long Size( 0 ), Hash( 0 );
00157 time_t ChangeDate( 0 );
00158 Dedupe::FileInfo::FileType Type( Dedupe::FileInfo::TNotDefined );
00159 bool Keep( false );
00160
00161
00162 int cols = sqlite3_column_count( stmt );
00163
00164
00165 std::string name, value;
00166 while ( sqlite3_step( stmt ) == SQLITE_ROW )
00167 {
00168 for( int i = 0; i < cols; i++ )
00169 {
00170 if( !sqlite3_column_name( stmt, i ) ) continue;
00171
00172 name = sqlite3_column_name( stmt, i );
00173 if( name.empty() ) continue;
00174
00175 if( name == "Path" )
00176 {
00177 Path = reinterpret_cast<const char*>( sqlite3_column_text( stmt, i ));
00178 }
00179
00180 if( name == "Size" )
00181 {
00182 Size = sqlite3_column_int64( stmt, i );
00183 }
00184
00185 if( name == "ChangeDate")
00186 {
00187 ChangeDate = sqlite3_column_int64( stmt, i );
00188 }
00189
00190 if( name == "Hash" )
00191 {
00192 Hash = sqlite3_column_int64( stmt, i );
00193 }
00194
00195 if( name == "Type" )
00196 {
00197 Type = static_cast<Dedupe::FileInfo::FileType>(sqlite3_column_int( stmt, i ));
00198 }
00199
00200 if( name == "Keep" )
00201 {
00202 Keep = sqlite3_column_int( stmt, i );
00203 }
00204
00205 }
00206 Dedupe::FileInfo Current( Path, Size, ChangeDate, Type, Keep, Hash );
00207
00208 ReturningInfos.push_back( Current );
00209 }
00210
00211 return ReturningInfos;
00212 }
00213
00214 Dedupe::FileStream Dataholding::SqlExec( const std::string &SqlCommand )
00215 {
00216 sqlite3_stmt* stmt;
00217 const char* PointerToCommand = SqlCommand.c_str();
00218 int size = SqlCommand.size();
00219 const char* NextSqlCommand = NULL;
00220
00221 Dedupe::FileStream Returning;
00222
00223
00224 while( PointerToCommand != NULL )
00225 {
00226 Dedupe::Dataholding::SqliteWrapper::Check( sqlite3_prepare_v2(
00227 db_handle, PointerToCommand, size, &stmt, &NextSqlCommand ) );
00228
00229
00230 if( strlen( NextSqlCommand ) != 0 ) PointerToCommand = NextSqlCommand;
00231 else PointerToCommand = NULL;
00232
00233
00234 Returning = ExecStatement( stmt );
00235 }
00236 sqlite3_finalize( stmt );
00237
00238 return Returning;
00239 }
00240
00241
00242