Logo Search packages:      
Sourcecode: kat version File versions  Download package

katscanfolder.cpp

/***************************************************************************
 *   Copyright (C) 2005 by Roberto Cappuccio and the Kat team              *
 *   Roberto Cappuccio : roberto.cappuccio@gmail.com                       *
 *   Praveen Kandikuppa : praveen9@gmail.com                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.           *
 ***************************************************************************/

#include <kdebug.h>
#include <kglobal.h>
#include <qapplication.h>
#include <qtimer.h>
#include <qdir.h>
#include <qregexp.h>

#include <katscanfolder.h>
#include <katxattr.h>
#include <config.h>

using namespace KIO;

KatScanFolder::KatScanFolder( KatCatalog* cat, CppSQLite3DB* db )
    : QObject( 0, "katscanfolder" ), m_db( db ), m_cat( cat ), m_bAsync( true ),
    m_totalSize( 0L ), m_totalFiles( 0L ), m_totalSubdirs( 0L )
{
    m_totalSize = m_cat->fileSize();
    m_totalFiles = m_cat->files();
    m_totalSubdirs = m_cat->folders();

}

KatScanFolder* KatScanFolder::scanFolderJob( KatCatalog* cat, CppSQLite3DB* db )
{
    return new KatScanFolder( cat, db );
}

// database functions
int KatScanFolder::openTransaction()
{
    try
    {
        m_db->execDML( "begin transaction;" );
    }
    catch ( CppSQLite3Exception& e )
    {
        kdDebug() << e.errorMessage() << endl;
        return e.errorCode();
    }
    return 0;
}

int KatScanFolder::commitTransaction()
{
    try
    {
        m_db->execDML( "commit transaction;" );

    }
    catch ( CppSQLite3Exception& e )
    {
        kdDebug() << e.errorMessage() << endl;
        return e.errorCode();
    }
    return 0;
}

inline void KatScanFolder::setAttributes ( const QString &path, int fileid, time_t current_time )
{
#ifdef HAVE_ATTR_H
    KatExtendedAttr::setExtendedAttribute ( path, "fileid", QString::number( fileid ) );
    KatExtendedAttr::setExtendedAttribute ( path, "lastupdatedate", QString::number( current_time ) );
#endif
}

void KatScanFolder::addFiles( const QStringList& files )
{
    KFileItem *kfi;
    QString DML;
    int parentId;

    openTransaction();

    QStringList::ConstIterator it = files.begin();
    QStringList::ConstIterator end( files.end() );

    for (; it != end; ++it)
    {
        kfi = new KFileItem( KFileItem::Unknown, // _mode
                             KFileItem::Unknown, // _permissions
                             KURL::fromPathOrURL(*it), // url
                             true // determineMimeTypeOnDemand
                           );

        // FIXME -- what if this is a link??
        if (kfi->isLink())
      {
          delete kfi;
          kfi = 0;
            continue;
      }

        QString fullName = kfi->url().path(-1) ;
        unsigned pos = fullName.findRev( '/', -1 );
        QString fileName = fullName.right( fullName.length() - pos - 1 );
        QString path = fullName.left( pos );

        // TODO: Find a regular expression to eliminate all possible problems with filenames in SQL
        QString spath( path );
        spath = spath.replace( QRegExp("'"), "''" );

      //kdDebug () << "Adding file/dir to the files database " << *it << " : " << fullName << endl;

        // Find the parent of current file
        try
        {
            DML = "select fileid from files where fullname = '" + spath + "';";
            CppSQLite3Query q = m_db->execQuery( DML );

            if ( !q.eof() )
                parentId = q.getIntField( "fileid" );
            else
                parentId = -1L;

            q.finalize();

        }
        catch ( CppSQLite3Exception& e )
        {
            kdDebug() << e.errorMessage() << endl;
            delete kfi;
            kfi = 0;
            continue;
        }

        // Save the basic information into the files table
        try
        {
            time_t current_time = QDateTime::currentDateTime().toTime_t();

            CppSQLite3Statement stmt = m_db->compileStatement( "insert into files("
                                                                                  "catalogid, "
                                                                                  "fullname,"
                                                                                  "filename,"
                                                                                  "parentid,"
                                                                                  "filetype,"
                                                                                  "filesize,"
                                                                                  "statuschangedate,"
                                                                                  "modificationdate,"
                                                                                  "lastaccessdate,"
                                                                                  "lastupdatedate,"
                                                                                  "username,"
                                                                                  "groupname,"
                                                                                  "permissions,"
                                                                                  "mode,"
                                                                                  "language"
                                                                                  ") values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
                                                              );
            stmt.bind(  1, m_cat->catalogId() );
            stmt.bind(  2, kfi->url().path(-1) );
            stmt.bind(  3, fileName );
            stmt.bind(  4, parentId );
            stmt.bind(  5, kfi->mimetype() );
            stmt.bind(  6, (long)kfi->size() );
            stmt.bind(  7, kfi->time( KIO::UDS_CREATION_TIME ) );
            stmt.bind(  8, kfi->time( KIO::UDS_MODIFICATION_TIME ) );
            stmt.bind(  9, kfi->time( KIO::UDS_ACCESS_TIME ) );
            stmt.bind( 10, current_time);
            stmt.bind( 11, kfi->user() );
            stmt.bind( 12, kfi->group() );
            stmt.bind( 13, kfi->permissions() );
            stmt.bind( 14, kfi->mode() );
            stmt.bind( 15, QString::null );

            stmt.execDML();
            stmt.finalize();

            if ( m_cat->useExtendedAttr() )
                setAttributes ( kfi->url().path(-1), m_db->lastRowId(), current_time );
        }
        catch ( CppSQLite3Exception& e )
        {
            kdDebug() << e.errorMessage() << " : " << kfi->url().path(-1) << endl;
            delete kfi;
            kfi = 0;
            continue;
        }

        // Update file size, number of folders, number of files
        if (!kfi->isDir())
        {
            m_totalSize += kfi->size();
            m_cat->setFileSize (m_totalSize);

            m_totalFiles ++;
            m_cat->setFiles (m_totalFiles);
        }
        else
        {
            m_totalSubdirs ++;
            m_cat->setFolders (m_totalSubdirs);
        }

        delete kfi;
        kfi = 0;
    }

    commitTransaction();
}

void KatScanFolder::updateFiles( const QStringList& files )
{
    KFileItem *kfi;
    int fileId;
    KIO::filesize_t oldSize = 0;

    QString DML;

    // NOTE -- see if this works properly
    openTransaction();

    QStringList::ConstIterator it = files.begin();
    QStringList::ConstIterator end( files.end() );
    for (; it != end; ++it)
    {
        fileId = 0;
        try
        {
            DML = "select filesize,fileid from files where fullname = '" + *it + "';";
            CppSQLite3Query q = m_db->execQuery( DML );

            if ( !q.eof() ) {
                fileId = q.getIntField( "fileid" );
                oldSize = q.getIntField( "filesize" );
            }
            q.finalize();
        }
        catch ( CppSQLite3Exception& e )
        {
            kdDebug() << e.errorMessage() << endl;
        }

        if (!fileId) {
            kdDebug() << "file/dir " << *it << " does not exist in database, yet an update is requested" << endl;
            continue;
        }
      //kdDebug () << "Updating file/dir to the files database " << *it << endl;

        kfi = new KFileItem( KFileItem::Unknown, // _mode
                             KFileItem::Unknown, // _permissions
                             KURL( *it ), // url
                             true // determineMimeTypeOnDemand
                           );

        if ( !kfi->isLink() )
        {
            m_cat->setFileSize( m_cat->fileSize() + kfi->size() - oldSize);

            try
            {
                time_t current_time = QDateTime::currentDateTime().toTime_t();
                CppSQLite3Statement stmt = m_db->compileStatement( "update files set "
                                                                                   "filetype = ?, "
                                                                                   "filesize = ?, "
                                                                                   "statuschangedate = ?, "
                                                                                   "modificationdate = ?, "
                                                                                   "lastaccessdate = ?, "
                                                                                   "lastupdatedate = ?, "
                                                                                   "username = ?, "
                                                                                   "groupname = ?, "
                                                                                   "permissions = ?, "
                                                                                   "mode = ?, "
                                                                                   "language = ? "
                                                                                   "where fileid='" + QString::number(fileId) + "';");
                stmt.bind(  1, kfi->mimetype() );
                stmt.bind(  2, (long)kfi->size() );
                stmt.bind(  3, kfi->time( KIO::UDS_CREATION_TIME ) );
                stmt.bind(  4, kfi->time( KIO::UDS_MODIFICATION_TIME ) );
                stmt.bind(  5, kfi->time( KIO::UDS_ACCESS_TIME ) );
                stmt.bind(  6, current_time );
                stmt.bind(  7, kfi->user() );
                stmt.bind(  8, kfi->group() );
                stmt.bind(  9, kfi->permissions() );
                stmt.bind( 10, kfi->mode() );
                stmt.bind( 11, QString::null );

                stmt.execDML();
                stmt.finalize();

                if ( m_cat->useExtendedAttr() )
                    setAttributes ( *it, fileId, current_time );
            }
            catch ( CppSQLite3Exception& e )
            {
                kdDebug() << e.errorMessage() << " : " << kfi->url().path() << endl;
            }
        }
        delete kfi;
        kfi = 0;
    }

    commitTransaction();
}

void KatScanFolder::deleteFiles ( const QStringList& nfiles )
{
    // Get the fileid for the current file
    int fileId;
    KIO::filesize_t fileSize = 0;
    QString fileType;

    QStringList files = nfiles;

    // NOTE -- see if this works properly
    openTransaction();

    while (!files.empty())
    {
        fileId = 0;

        // Get the first file to act upon
        QString file = files[0];
        files.pop_front();
        try
        {
            CppSQLite3Query q = m_db->execQuery ("select filetype,filesize,fileid from files where fullname='" + file + "';" );

            if (!q.eof()) {
                fileId = q.getIntField( "fileid" );
                fileType = q.getStringField( "filetype" );
                fileSize = q.getIntField( "filesize" );
            }
            q.finalize();
        }
        catch ( CppSQLite3Exception& e )
        {
            kdDebug() << e.errorMessage() << " : " << file << endl;
        }

        if (!fileId)
            continue;

        // Delete the current file from the database
        try
        {
            m_db->execDML( "delete from files where fileid = " + QString::number(fileId) + ";" );

            if (fileType == "inode/directory")
            {
                m_totalSubdirs --;
                m_cat->setFolders (m_totalSubdirs);
            }
            else
            {
                m_totalFiles --;
                m_cat->setFiles (m_totalFiles);

                m_totalSize -= fileSize;
                m_cat->setFileSize (m_totalSize);
            }
        }
        catch ( CppSQLite3Exception& e )
        {
            kdDebug() << e.errorMessage() << " : " << fileId << endl;
        }
    }

    commitTransaction();
}

void KatScanFolder::moveFiles( const QMap<QString, QString>& moveMap)
{
    QMap<QString, QString>::ConstIterator it = moveMap.begin();
    QMap<QString, QString>::ConstIterator end(  moveMap.end() );
    for (; it!= end; ++it)
        handleMove (it.data(), it.key());
}

void KatScanFolder::rename ( const QString& from, const QString& to )
{
    try
    {
        m_db->execDML ("update files set fullname='" + to + "' where fullname='" + from + "';" );
        //updateFiles (to);
    }
    catch ( CppSQLite3Exception& e )
    {
        kdDebug() << e.errorMessage() << endl;
    }
}

void KatScanFolder::handleMove ( const QString& from, const QString& to )
{
    // Get the fileid for the current file
    QStringList folders(from);
    int fileid;

    // NOTE -- see if this works properly
    openTransaction();

    while (!folders.empty())
    {
        // Get the first folder to act upon
        QString cur_from = folders[0];
        folders.pop_front();
        try
        {
            QString cur_to = to;
            fileid = 0;

            CppSQLite3Query q = m_db->execQuery ("select fileid from files where fullname='" + cur_from + "';" );

            if (!q.eof())
                fileid = q.getIntField ("fileid");
            q.finalize();

            if (fileid) {
                // Now find all the files/folders whose parentid = fileid
                q = m_db->execQuery ("select fullname from files where parentid='" + QString::number(fileid) + "';" );

                while (!q.eof())
                {
                    folders.append(q.getStringField("fullname"));
                    q.nextRow();
                }
                q.finalize();
            }

            // Run move on the curent file/folder
            if (cur_from == from)
                rename (cur_from, cur_to);
            else
                rename (cur_from, cur_to.append("/").append(cur_from.latin1() + from.length() + 1));
        }
        catch ( CppSQLite3Exception& e )
        {
            kdDebug() << e.errorMessage() << endl;
        }
    }

    commitTransaction();
}

#include "katscanfolder.moc"


Generated by  Doxygen 1.6.0   Back to index