[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/sqlitebrowser/sqlitebrowser/sqlb-3.2.x/src/sqlitedb.cpp [Back]  [Original]

#include "sqlitedb.h"
#include "sqlitetablemodel.h"
#include "MainWindow.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

bool DBBrowserDB::isOpen ( ) const
{
    return _db!=0;
}

bool DBBrowserDB::getDirty() const
{
    return !savepointList.empty();
}

bool DBBrowserDB::open ( const QString & db)
{
    bool ok=false;
    int  err;

    if (isOpen()) close();

    //try to verify the SQLite version 3 file header
    QFile dbfile(db);
    if ( dbfile.open( QIODevice::ReadOnly ) ) {
        char buffer[16+1];
        dbfile.readLine(buffer, 16);
        QString contents = QString(buffer);
        dbfile.close();
        if (!contents.startsWith("SQLite format 3")) {
            lastErrorMessage = QObject::tr("File is not a SQLite 3 database");
            return false;
        }
    } else {
        lastErrorMessage = QObject::tr("File could not be read");
        return false;
    }

    lastErrorMessage = QObject::tr("no error");

    err = sqlite3_open_v2(db.toUtf8(), &_db, SQLITE_OPEN_READWRITE, NULL);
    if ( err ) {
        lastErrorMessage = QString::fromUtf8((const char*)sqlite3_errmsg(_db));
        sqlite3_close(_db);
        _db = 0;
        return false;
    }

    if (_db){
        // set preference defaults
        QSettings settings(QApplication::organizationName(), QApplication::organizationName());
        settings.sync();
        bool foreignkeys = settings.value( "/db/foreignkeys", false ).toBool();
        setPragma("foreign_keys", foreignkeys ? "1" : "0");

        if (SQLITE_OK==sqlite3_exec(_db,"PRAGMA empty_result_callbacks = ON;",
                                    NULL,NULL,NULL)){
            if (SQLITE_OK==sqlite3_exec(_db,"PRAGMA show_datatypes = ON;",
                                        NULL,NULL,NULL)){
                ok=true;
            }
            curDBFilename = db;
        }

        // Enable extension loading
        sqlite3_enable_load_extension(_db, 1);
    }

    return ok;
}

bool DBBrowserDB::setRestorePoint(const QString& pointname)
{
    if(!isOpen())
        return false;
    if(savepointList.contains(pointname))
        return true;

    if(_db)
    {
        QString query = QString("SAVEPOINT %1;").arg(pointname);
        sqlite3_exec(_db, query.toUtf8(), NULL, NULL, NULL);
        savepointList.append(pointname);
        if(mainWindow) mainWindow->dbState(getDirty());
    }
    return true;
}

bool DBBrowserDB::save(const QString& pointname)
{
    if(!isOpen() || savepointList.contains(pointname) == false)
        return false;

    if(_db)
    {
        QString query = QString("RELEASE %1;").arg(pointname);
        sqlite3_exec(_db, query.toUtf8(), NULL,NULL,NULL);
        savepointList.removeAll(pointname);
        if(mainWindow) mainWindow->dbState(getDirty());
    }
    return true;
}

bool DBBrowserDB::revert(const QString& pointname)
{
    if(!isOpen() || savepointList.contains(pointname) == false)
        return false;

    if(_db)
    {
        QString query = QString("ROLLBACK TO SAVEPOINT %1;").arg(pointname);
        sqlite3_exec(_db, query.toUtf8(), NULL, NULL, NULL);
        query = QString("RELEASE %1;").arg(pointname);
        sqlite3_exec(_db, query.toUtf8(), NULL, NULL, NULL);
        savepointList.removeAll(pointname);
        if(mainWindow) mainWindow->dbState(getDirty());
    }
    return true;
}

bool DBBrowserDB::saveAll()
{
    foreach(const QString& point, savepointList)
    {
        if(!save(point))
            return false;
    }
    return true;
}

bool DBBrowserDB::revertAll()
{
    foreach(const QString& point, savepointList)
    {
        if(!revert(point))
            return false;
    }
    return true;
}

bool DBBrowserDB::create ( const QString & db)
{
    bool ok=false;
    
    if (isOpen()) close();

    lastErrorMessage = QObject::tr("no error");

    // read encoding from settings and open with sqlite3_open for utf8
    // and sqlite3_open16 for utf16
    QSettings settings(QApplication::organizationName(), QApplication::organizationName());
    QString sEncoding = settings.value("/db/defaultencoding", "UTF-8").toString();

    int openresult = SQLITE_OK;

    if(sEncoding == "UTF-8" || sEncoding == "UTF8" || sEncoding == "Latin1")
        openresult = sqlite3_open(db.toUtf8(), &_db);
    else
        openresult = sqlite3_open16(db.utf16(), &_db);

    if( openresult != SQLITE_OK ){
        lastErrorMessage = QString::fromUtf8((const char*)sqlite3_errmsg(_db));
        sqlite3_close(_db);
        _db = 0;
        return false;
    }

    if (_db){
        if (SQLITE_OK==sqlite3_exec(_db,"PRAGMA empty_result_callbacks = ON;",
                                    NULL,NULL,NULL)){
            if (SQLITE_OK==sqlite3_exec(_db,"PRAGMA show_datatypes = ON;",
                                        NULL,NULL,NULL)){
                ok=true;
            }
            curDBFilename = db;
        }

        // Enable extension loading
        sqlite3_enable_load_extension(_db, 1);
    }

    return ok;
}


bool DBBrowserDB::close()
{
    if(_db)
    {
        if (getDirty())
        {
            QMessageBox::StandardButton reply = QMessageBox::question(0,
                                                                      QApplication::applicationName(),
                                                                      QObject::tr("Do you want to save the changes "
                                                                                  "made to the database file %1?").arg(curDBFilename),
                                                                      QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);

            // If the user clicked the cancel button stop here and return false
            if(reply == QMessageBox::Cancel)
                return false;

            // If he didn't it was either yes or no
            if(reply == QMessageBox::Yes)
                saveAll();
            else
                revertAll(); //not really necessary, I think... but will not hurt.
        }
        sqlite3_close(_db);
    }
    _db = 0;
    objMap.clear();
    savepointList.clear();
    if(mainWindow) mainWindow->dbState(getDirty());

    // Return true to tell the calling function that the closing wasn't cancelled by the user
    return true;
}

bool DBBrowserDB::dump(const QString& filename)
{
    // Open file
    QFile file(filename);
    if(file.open(QIODevice::WriteOnly))
    {
        // Create progress dialog. For this count the number of all table rows to be exported first;
        // this does neither take the table creation itself nor
        // indices, views or triggers into account but compared to the number of rows those should be neglectable
        unsigned int numRecordsTotal = 0, numRecordsCurrent = 0;
        QList tables = objMap.values("table");
        QMutableListIterator it(tables);
        while(it.hasNext())
        {
            it.next();

            // Remove the sqlite_stat1 table if there is one
            if(it.value().getname() == "sqlite_stat1" || it.value().getname() == "sqlite_sequence")
            {
                it.remove();
            } else {
                // Otherwise get the number of records in this table
                SqliteTableModel tableModel(0, this);
                tableModel.setTable(it.value().getname());
                numRecordsTotal += tableModel.totalRowCount();
            }
        }
        QProgressDialog progress(QObject::tr("Exporting database to SQL file..."),
                                 QObject::tr("Cancel"), 0, numRecordsTotal);
        progress.setWindowModality(Qt::ApplicationModal);

        // Regular expression to check for numeric strings
        QRegExp regexpIsNumeric("\\d*");

        // Open text stream to the file
        QTextStream stream(&file);

        // Put the SQL commands in a transaction block
        stream 

Web Proxy Viewer  |  New URL  |  Original Page