diff options
Diffstat (limited to 'kexi/plugins/scripting/kexidb/kexidbcursor.cpp')
-rw-r--r-- | kexi/plugins/scripting/kexidb/kexidbcursor.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/kexi/plugins/scripting/kexidb/kexidbcursor.cpp b/kexi/plugins/scripting/kexidb/kexidbcursor.cpp new file mode 100644 index 00000000..3bc1763d --- /dev/null +++ b/kexi/plugins/scripting/kexidb/kexidbcursor.cpp @@ -0,0 +1,139 @@ +/*************************************************************************** + * kexidbcursor.cpp + * This file is part of the KDE project + * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "kexidbcursor.h" +#include "kexidbconnection.h" + +#include <kexidb/tableschema.h> +#include <kexidb/queryschema.h> + +#include <kdebug.h> + +using namespace Kross::KexiDB; + +KexiDBCursor::KexiDBCursor(::KexiDB::Cursor* cursor) + : Kross::Api::Class<KexiDBCursor>("KexiDBCursor") + , m_cursor(cursor) +{ + this->addFunction0<Kross::Api::Variant>("open", this, &KexiDBCursor::open ); + this->addFunction0<Kross::Api::Variant>("isOpened", this, &KexiDBCursor::isOpened ); + this->addFunction0<Kross::Api::Variant>("reopen", this, &KexiDBCursor::reopen ); + this->addFunction0<Kross::Api::Variant>("close", this, &KexiDBCursor::close ); + this->addFunction0<Kross::Api::Variant>("moveFirst", this, &KexiDBCursor::moveFirst ); + this->addFunction0<Kross::Api::Variant>("moveLast", this, &KexiDBCursor::moveLast ); + this->addFunction0<Kross::Api::Variant>("movePrev", this, &KexiDBCursor::movePrev ); + this->addFunction0<Kross::Api::Variant>("moveNext", this, &KexiDBCursor::moveNext ); + this->addFunction0<Kross::Api::Variant>("bof", this, &KexiDBCursor::bof ); + this->addFunction0<Kross::Api::Variant>("eof", this, &KexiDBCursor::eof ); + this->addFunction0<Kross::Api::Variant>("at", this, &KexiDBCursor::at ); + this->addFunction0<Kross::Api::Variant>("fieldCount", this, &KexiDBCursor::fieldCount ); + this->addFunction1<Kross::Api::Variant, Kross::Api::Variant>("value", this, &KexiDBCursor::value ); + this->addFunction2<Kross::Api::Variant, Kross::Api::Variant, Kross::Api::Variant>("setValue", this, &KexiDBCursor::setValue ); + this->addFunction0<Kross::Api::Variant>("save", this, &KexiDBCursor::save ); +} + +KexiDBCursor::~KexiDBCursor() +{ + ///@todo check ownership + //delete m_cursor; + + clearBuffers(); +} + +void KexiDBCursor::clearBuffers() +{ + QMap<Q_LLONG, Record*>::ConstIterator + it( m_modifiedrecords.constBegin() ), end( m_modifiedrecords.constEnd() ); + for( ; it != end; ++it) + delete it.data(); + m_modifiedrecords.clear(); +} + +const QString KexiDBCursor::getClassName() const +{ + return "Kross::KexiDB::KexiDBCursor"; +} + +bool KexiDBCursor::open() { return m_cursor->open(); } +bool KexiDBCursor::isOpened() { return m_cursor->isOpened(); } +bool KexiDBCursor::reopen() { return m_cursor->reopen(); } +bool KexiDBCursor::close() { return m_cursor->close(); } + +bool KexiDBCursor::moveFirst() { return m_cursor->moveFirst(); } +bool KexiDBCursor::moveLast() { return m_cursor->moveLast(); } +bool KexiDBCursor::movePrev() { return m_cursor->movePrev(); } +bool KexiDBCursor::moveNext() { return m_cursor->moveNext(); } + +bool KexiDBCursor::bof() { return m_cursor->bof(); } +bool KexiDBCursor::eof() { return m_cursor->eof(); } + +Q_LLONG KexiDBCursor::at() { return m_cursor->at(); } +uint KexiDBCursor::fieldCount() { return m_cursor->fieldCount(); } + +QVariant KexiDBCursor::value(uint index) +{ + return m_cursor->value(index); +} + +bool KexiDBCursor::setValue(uint index, QVariant value) +{ + ::KexiDB::QuerySchema* query = m_cursor->query(); + if(! query) { + kdDebug() << "Invalid query in KexiDBCursor::setValue index=" << index << " value=" << value << endl; + return false; + } + + ::KexiDB::QueryColumnInfo* column = query->fieldsExpanded().at(index); + if(! column) { + kdDebug() << "Invalid column in KexiDBCursor::setValue index=" << index << " value=" << value << endl; + return false; + } + + const Q_LLONG position = m_cursor->at(); + if(! m_modifiedrecords.contains(position)) + m_modifiedrecords.replace(position, new Record(m_cursor)); + m_modifiedrecords[position]->buffer->insert(*column, value); + return true; +} + +bool KexiDBCursor::save() +{ + if(m_modifiedrecords.count() < 1) + return true; + + //It is needed to close the cursor before we are able to update the rows + //since else the database could be locked (e.g. at the case of SQLite a + //KexiDB: Object ERROR: 6: SQLITE_LOCKED would prevent updating). + //Maybe it works fine with other drivers like MySQL or Postqre? + m_cursor->close(); + + bool ok = true; + QMap<Q_LLONG, Record*>::ConstIterator + it( m_modifiedrecords.constBegin() ), end( m_modifiedrecords.constEnd() ); + for( ; it != end; ++it) { + bool b = m_cursor->updateRow(it.data()->rowdata, * it.data()->buffer, m_cursor->isBuffered()); + if(ok) { + ok = b; + //break; + } + } + //m_cursor->close(); + clearBuffers(); + return ok; +} |