kexi

kexidbcursor.cpp

00001 /***************************************************************************
00002  * kexidbcursor.cpp
00003  * This file is part of the KDE project
00004  * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "kexidbcursor.h"
00021 #include "kexidbconnection.h"
00022 
00023 #include <kexidb/tableschema.h>
00024 #include <kexidb/queryschema.h>
00025 
00026 #include <kdebug.h>
00027 
00028 using namespace Kross::KexiDB;
00029 
00030 KexiDBCursor::KexiDBCursor(::KexiDB::Cursor* cursor)
00031     : Kross::Api::Class<KexiDBCursor>("KexiDBCursor")
00032     , m_cursor(cursor)
00033 {
00034     this->addFunction0<Kross::Api::Variant>("open", this, &KexiDBCursor::open );
00035     this->addFunction0<Kross::Api::Variant>("isOpened", this, &KexiDBCursor::isOpened );
00036     this->addFunction0<Kross::Api::Variant>("reopen", this, &KexiDBCursor::reopen );
00037     this->addFunction0<Kross::Api::Variant>("close", this, &KexiDBCursor::close );
00038     this->addFunction0<Kross::Api::Variant>("moveFirst", this, &KexiDBCursor::moveFirst );
00039     this->addFunction0<Kross::Api::Variant>("moveLast", this, &KexiDBCursor::moveLast );
00040     this->addFunction0<Kross::Api::Variant>("movePrev", this, &KexiDBCursor::movePrev );
00041     this->addFunction0<Kross::Api::Variant>("moveNext", this, &KexiDBCursor::moveNext );
00042     this->addFunction0<Kross::Api::Variant>("bof", this, &KexiDBCursor::bof );
00043     this->addFunction0<Kross::Api::Variant>("eof", this, &KexiDBCursor::eof );
00044     this->addFunction0<Kross::Api::Variant>("at", this, &KexiDBCursor::at );
00045     this->addFunction0<Kross::Api::Variant>("fieldCount", this, &KexiDBCursor::fieldCount );
00046     this->addFunction1<Kross::Api::Variant, Kross::Api::Variant>("value", this, &KexiDBCursor::value );
00047     this->addFunction2<Kross::Api::Variant, Kross::Api::Variant, Kross::Api::Variant>("setValue", this, &KexiDBCursor::setValue );
00048     this->addFunction0<Kross::Api::Variant>("save", this, &KexiDBCursor::save );
00049 }
00050 
00051 KexiDBCursor::~KexiDBCursor()
00052 {
00054     //delete m_cursor;
00055 
00056     clearBuffers();
00057 }
00058 
00059 void KexiDBCursor::clearBuffers()
00060 {
00061     QMap<Q_LLONG, Record*>::ConstIterator
00062         it( m_modifiedrecords.constBegin() ), end( m_modifiedrecords.constEnd() );
00063     for( ; it != end; ++it)
00064         delete it.data();
00065     m_modifiedrecords.clear();
00066 }
00067 
00068 const QString KexiDBCursor::getClassName() const
00069 {
00070     return "Kross::KexiDB::KexiDBCursor";
00071 }
00072 
00073 bool KexiDBCursor::open() { return m_cursor->open(); }
00074 bool KexiDBCursor::isOpened() { return m_cursor->isOpened(); }
00075 bool KexiDBCursor::reopen() { return m_cursor->reopen(); }
00076 bool KexiDBCursor::close() { return m_cursor->close(); }
00077 
00078 bool KexiDBCursor::moveFirst() { return m_cursor->moveFirst(); }
00079 bool KexiDBCursor::moveLast() { return m_cursor->moveLast(); }
00080 bool KexiDBCursor::movePrev() { return m_cursor->movePrev(); }
00081 bool KexiDBCursor::moveNext() { return m_cursor->moveNext(); }
00082 
00083 bool KexiDBCursor::bof() { return m_cursor->bof(); }
00084 bool KexiDBCursor::eof() { return m_cursor->eof(); }
00085 
00086 Q_LLONG KexiDBCursor::at() { return m_cursor->at(); }
00087 uint KexiDBCursor::fieldCount() { return m_cursor->fieldCount(); }
00088 
00089 QVariant KexiDBCursor::value(uint index)
00090 {
00091     return m_cursor->value(index);
00092 }
00093 
00094 bool KexiDBCursor::setValue(uint index, QVariant value)
00095 {
00096     ::KexiDB::QuerySchema* query = m_cursor->query();
00097     if(! query) {
00098         kdDebug() << "Invalid query in KexiDBCursor::setValue index=" << index << " value=" << value << endl;
00099         return false;
00100     }
00101 
00102     ::KexiDB::QueryColumnInfo* column = query->fieldsExpanded().at(index);
00103     if(! column) {
00104         kdDebug() << "Invalid column in KexiDBCursor::setValue index=" << index << " value=" << value << endl;
00105         return false;
00106     }
00107 
00108     const Q_LLONG position = m_cursor->at();
00109     if(! m_modifiedrecords.contains(position))
00110         m_modifiedrecords.replace(position, new Record(m_cursor));
00111     m_modifiedrecords[position]->buffer->insert(*column, value);
00112     return true;
00113 }
00114 
00115 bool KexiDBCursor::save()
00116 {
00117     if(m_modifiedrecords.count() < 1)
00118         return true;
00119 
00120     //It is needed to close the cursor before we are able to update the rows
00121     //since else the database could be locked (e.g. at the case of SQLite a
00122     //KexiDB: Object ERROR: 6: SQLITE_LOCKED would prevent updating).
00123     //Maybe it works fine with other drivers like MySQL or Postqre?
00124     m_cursor->close();
00125 
00126     bool ok = true;
00127     QMap<Q_LLONG, Record*>::ConstIterator
00128         it( m_modifiedrecords.constBegin() ), end( m_modifiedrecords.constEnd() );
00129     for( ; it != end; ++it) {
00130         bool b = m_cursor->updateRow(it.data()->rowdata, * it.data()->buffer, m_cursor->isBuffered());
00131         if(ok) {
00132             ok = b;
00133             //break;
00134         }
00135     }
00136     //m_cursor->close();
00137     clearBuffers();
00138     return ok;
00139 }
KDE Home | KDE Accessibility Home | Description of Access Keys