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

FLSqlCursor.cpp

/***************************************************************************
                          FLSqlCursor.cpp  -  description
                             -------------------
    begin                : Fri Jul 27 2001
    copyright            : (C) 2001,2002 by Federico Albujer Zornoza
    email                : mail@infosial.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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "FLSqlCursor.h"
#include "FLApplication.h"
#include "FLTableMetaData.h"
#include "FLFieldMetaData.h"
#include "FLRelationMetaData.h"
#include "FLManager.h"
#include "FLFormRecordDB.h"
#include "FLAction.h"
#include "FLReceiver.h"
#include "../process/FLInterface.h"

// Globales
int
  FLSqlCursor::transaction_;

00033 FLSqlCursor::FLSqlCursor (const QString & name, bool autopopulate, QSqlDatabase * db, FLSqlCursor * cR, FLRelationMetaData * r):
QObject (),
QSqlCursor (QString::null, autopopulate, db),
buffer_ (0),
bufferCopy_(0),
metadata_ (0),
edition (true),
browse (true),
mainFilter_ (QString::null),
action_ (0)
{
  if (!FLManager::existsTable (name))
      metadata_ = FLManager::createTable (name);
  else
      metadata_ = FLManager::metadata (name);

  cursorRelation = cR;
  relation = r;

  if (!metadata_)
      return;

  QSqlCursor::setName (metadata_->name (), autopopulate);

  modeAccess_ = BROWSE;
  if (cR && r)
      {
        connect (cR, SIGNAL (bufferChanged (QString)), this, SLOT (refresh (QString)));
        connect (cR, SIGNAL (newBuffer ()), this, SLOT (refresh ()));
        connect (cR, SIGNAL (cursorUpdated ()), this, SLOT (refresh ()));
      }
  else
      seek (0);
}

00068 FLSqlCursor::~FLSqlCursor ()
{
  if (metadata_)
      delete metadata_;

  if (action_)
      delete action_;

      if (bufferCopy_)
            delete bufferCopy_;
}

void
00081 FLSqlCursor::refresh (QString fN)
{
  if (!metadata_)
      return;

  if (cursorRelation && relation && metadata_)
      {
        QString fgN = relation->foreignField ();
        if (fN.isEmpty () || fgN == fN)
            {
              QString fgValue = cursorRelation->valueBuffer (fgN).toString ();
              select ("upper(" + relation->field () + ")=" + FLManager::formatValue (metadata_->field (relation->field ()), QVariant (fgValue.upper ())));
              modeAccess_ = BROWSE;
              seek (0);
              emit cursorUpdated ();
            }
      }
  else
      {
        select ("");
        modeAccess_ = BROWSE;
        seek (0);
        emit cursorUpdated ();
      }
}

void
00108 FLSqlCursor::refreshBuffer ()
{
  if (!metadata_)
      return;

  if (!isValid () && modeAccess_ != INSERT)
      {
        buffer_ = 0;
        emit newBuffer ();

        return;
      }
 
  switch (modeAccess_)
      {
      case INSERT:
        {
            buffer_ = primeInsert ();
            
            FLTableMetaData::FLFieldMetaDataList * fieldList = metadata_->fieldList ();
            FLFieldMetaData *field;

            for (unsigned int i = 0; i < fieldList->count (); i++)
              {
                  field = fieldList->at (i);

                  if ( field->defaultValue().isValid() )
                        {
                        if ( (field->type() == QVariant::Bool) || (field->type()==FLFieldMetaData::Unlock))
                        {
                                    if ( field->defaultValue().toString()=="true" )
                                    buffer_->setValue(field->name(), QVariant(true));
                                    else
                                    buffer_->setValue(field->name(), QVariant(false));
                        }
                        else
                        buffer_->setValue(field->name(), field->defaultValue());
                        }
          
                  if (field->type () == FLFieldMetaData::Serial)
                    {
                        QString seq = metadata_->name () + "_" + field->name () + "_seq";
                        QSqlQuery query ("SELECT nextval('" + seq + "');");

                        query.next ();
                        buffer_->setValue (field->name (), query.value (0));
                    }
                  //Código para rellenar el campo contador, por Andrés Otón Urbano
                  if (field->isCounter ())
                    {
                        FLReceiver *r = FLInterface::getReceiver (action_->process ());
                        QVariant siguiente;
                        if (r)
                          {
                              r->setCursor (this);
                              siguiente = r->calculateCounter (field->name ());
                          }
                        if (siguiente.isValid ())
                          {
                              buffer_->setValue (field->name (), siguiente);
                          }
                    }
              }

      if (cursorRelation && relation)
              setValueBuffer (relation->field (), cursorRelation->valueBuffer (relation->foreignField ()).toString ());

            updateBufferCopy();
            emit newBuffer ();
        }
        break;

      case EDIT:
            {
                  buffer_ = primeUpdate ();

                  FLTableMetaData::FLFieldMetaDataList * fieldList = metadata_->fieldList ();
                  FLFieldMetaData *field;

                  if (fieldList)
                        {
                              for (unsigned int i = 0; i < fieldList->count (); i++)
                                    {
                                          field = fieldList->at (i);
                                          if (field->type () == FLFieldMetaData::Unlock)
                                          if (!valueBuffer (field->name ()).toBool ())
                                                {
                                                      modeAccess_ = BROWSE;
                                                      refreshBuffer();
                                                      return;
                                                }
                                    }
                        }

                  updateBufferCopy();
                  emit newBuffer ();
            }

        break;

      case DEL:
        buffer_ = primeDelete ();
        break;

      case BROWSE:
        buffer_ = editBuffer (true);
        emit newBuffer ();

        break;
      }
}

00220 bool FLSqlCursor::checkIntegrity ()
{
  if (!buffer_ || !metadata_)
      return false;

  if (modeAccess_ == INSERT || modeAccess_ == EDIT)
      {
        FLTableMetaData::FLFieldMetaDataList * fieldList = metadata_->fieldList ();
        bool
            checkedCK =
            false;

        FLFieldMetaData *
            field;

        QString
            msg =
            "\n";

        for (unsigned int i = 0; i < fieldList->count (); i++)
            {
              field = fieldList->at (i);

              QString
                  s =
                  buffer_->
                  value (field->name ()).
                  toString ();

              if (s.isEmpty () && !field->allowNull ())
                  msg += "\n" + field->alias () + tr (" : No puede ser nulo");

              if ((field->isPrimaryKey () || field->isUnique ()) && modeAccess_ == INSERT)
                  {
                    QSqlCursor
                    c (metadata_->name ());

                    c.setFilter ("upper(" + field->name () + ")=" + FLManager::formatValue (field, QVariant (s.upper ())));
                    c.select ();

                    if (c.next ())
                        msg += "\n" + field->alias () + tr (" : Requiere valores únicos, y ya hay otro registro con el valor ") + s + tr (" en este campo");
                  }

              if (field->relationM1 () && !s.isEmpty ())
                  {

                    const FLRelationMetaData *
                        r =
                        field->
                        relationM1 ();

                    FLSqlCursor
                    c (r->foreignTable ());

                    c.setFilter ("upper(" + r->foreignField () + ")=" + FLManager::formatValue (field, QVariant (s.upper ())));
                    c.QSqlCursor::select ();

                    if (!c.next ())
                        msg += "\n" + field->alias () + tr (" : El valor ") + s + tr (" no existe en la tabla ") + c.metadata ()->alias ();
                  }

              FLTableMetaData::FLFieldMetaDataList * fieldListCK = metadata_->fieldListOfCompoundKey (field->name ());
              if (fieldListCK && !checkedCK && modeAccess_ == INSERT)
                  {
                    if (!fieldListCK->isEmpty ())
                        {
                          FLFieldMetaData *
                              fieldCK;

                          QString
                              filter =
                              QString::null;
                          QString
                              fields =
                              QString::null;
                          QString
                              valuesFields =
                              QString::null;

                          for (unsigned int i = 0; i < fieldListCK->count (); i++)
                              {
                                fieldCK = fieldListCK->at (i);
                                QString
                                    sCK =
                                    buffer_->
                                    value (fieldCK->name ()).
                                    toString ();

                                if (filter.isEmpty ())
                                    filter += "upper(" + fieldCK->name () + ")=" + FLManager::formatValue (fieldCK, QVariant (sCK.upper ()));
                                else
                                    filter += " AND upper(" + fieldCK->name () + ")= " + FLManager::formatValue (fieldCK, QVariant (sCK.upper ()));

                                if (fields.isEmpty ())
                                    fields += fieldCK->alias ();
                                else
                                    fields += "+" + fieldCK->alias ();

                                if (valuesFields.isEmpty ())
                                    valuesFields += sCK;
                                else
                                    valuesFields += "+" + sCK;
                              }

                          QSqlCursor
                          c (metadata_->name ());

                          c.setFilter (filter);
                          c.select ();

                          if (c.next ())
                              msg += "\n" + fields + tr (" : Requiere valor único, y ya hay otro registro con el valor ") + valuesFields;

                          checkedCK = true;
                        }
                  }

              FLFieldMetaData *
                  fMD =
                  field->
                  associatedField ();

              if (fMD)
                  {
                    if (!field->relationM1 ())
                        {
                          msg += "\n" + tr ("FLSqlCursor : Error en metadatos, el campo ")
                              + field->name () + tr (" tiene un campo asociado pero no existe relación muchos a uno");
                          continue;
                        }
                    QSqlCursor
                    c (field->relationM1 ()->foreignTable ());
                    QString ss = buffer_->value (fMD->name ()).toString ();

                    QString filter =      "upper(" +  field->associatedFieldFilterTo () + ")=" +FLManager::formatValue (fMD, QVariant (ss.upper ()));
                    filter += " AND upper(" + field->relationM1 ()->foreignField () + ")=" + FLManager::formatValue (field, QVariant (s.upper ()));

                    c.setFilter (filter);
                    c.select ();

                    if (s.isEmpty ())
                        s = "NULO";
                    if (ss.isEmpty ())
                        ss = "NULO";
                    if (!c.next ())
                        msg += "\n" + field->alias () + " : " + s + tr (" no pertenece a ") + ss;
                  }
            }

        if (msg != "\n")
            {
              QMessageBox::warning (qApp->mainWidget (), tr ("Aviso"),
                                                tr ("No se puede insertar o modificar el  registro, porque :") + msg, QMessageBox::Ok, 0, 0);

              return false;
            }
      }

  if (modeAccess_ == DEL)
      {
        FLTableMetaData::FLFieldMetaDataList * fieldList = metadata_->fieldList ();

        FLFieldMetaData *
            field;

        QString
            msg =
            QString::null;

        for (unsigned int i = 0; i < fieldList->count (); i++)
            {
              field = fieldList->at (i);
              QString
                  s =
                  buffer_->
                  value (field->name ()).
                  toString ();

              FLFieldMetaData::FLRelationMetaDataList * relationList = field->relationList ();

              if (!relationList)
                  continue;

              if (!relationList->isEmpty ())
                  {
                    FLRelationMetaData *
                        r;

                    for (unsigned int i = 0; i < relationList->count (); i++)
                        {
                          r = relationList->at (i);
                          FLSqlCursor
                          c (r->foreignTable ());

                          if (!c.metadata ())
                              {
                                msg += "\n" + tr ("FLSqlCursor : Error en metadatos de la tabla ") + r->foreignTable ();
                                continue;
                              }

                          FLFieldMetaData *
                              f =
                              c.
                              metadata ()->
                              field (r->foreignField ());

                          if (f)
                              {
                                if (f->relationM1 ())
                                    if (f->relationM1 ()->deleteCascade ())
                                      continue;
                              }
                          else
                              {
                                msg += "\n" + tr ("FLSqlCursor : Error en metadatos ") + r->foreignField () + tr (" no es válido");
                                continue;
                              }

                          c.setFilter ("upper(" + r->foreignField () + ")=" + FLManager::formatValue (field, QVariant (s.upper ())));
                          c.QSqlCursor::select ();

                          if (c.next ())
                              msg += "\n" + field->alias () + tr (" : Con el valor ") + s +
                                tr (" hay registros en la tabla ") + c.metadata ()->name () + ":" + c.metadata ()->alias ();
                        }
                  }
            }

        if (!msg.isEmpty ())
            {
              QMessageBox::warning (qApp->mainWidget (), tr ("Aviso"), tr ("No se puede borrar registro, porque : ") + msg, QMessageBox::Ok, 0, 0);

              return false;
            }
      }

  return true;
}

00460 bool FLSqlCursor::commitBuffer ()
{
  if (!buffer_ || !metadata_)
      return false;

  if (!checkIntegrity ())
      return false;

  QVariant
      pK =
      valueBuffer (metadata_->primaryKey ());

  switch (modeAccess_)
      {
      case INSERT:
        if (cursorRelation && relation)
            setValueBuffer (relation->field (), cursorRelation->valueBuffer (relation->foreignField ()));
        insert (FALSE);
        break;

      case EDIT:
        update (FALSE);
        break;

      case DEL:
        del (FALSE);
        emit
        cursorUpdated ();
        break;

      case BROWSE:
        break;
      }

  QString
      sql =
      QString::null;

  if (!action_)
      action_ = FLManager::action (metadata_->name ());
  FLReceiver *
      r =
      FLInterface::getReceiver (action_->masterProcess ());

  if (r && (modeAccess_ == EDIT || modeAccess_ == INSERT))
      {
        FLTableMetaData::FLFieldMetaDataList * fieldList = metadata_->fieldList ();
        FLFieldMetaData *
            field;
        r->setCursor (this);

        for (unsigned int i = 0; i < fieldList->count (); i++)
            {
              field = fieldList->at (i);
              if (field->calculated ())
                  {
                    QVariant
                        v =
                        r->
                        calculateField (field->name ());

                    sql =
                        "UPDATE " + metadata_->name () + " SET " +
                        field->name () + "=" +
                        FLManager::formatValue (field, v) + " WHERE " +
                        metadata_->primaryKey () + "=" + FLManager::formatValue (metadata_->field (metadata_->primaryKey ()), pK) + ";";
                    QSqlQuery
                    q (sql);
                  }
            }
      }

  modeAccess_ = BROWSE;

  if (r)
      delete
        r;

  return true;
}

00541 bool FLSqlCursor::seek (int i, bool relative)
{
  bool
      b =
      QSqlCursor::seek (i, relative);

  refreshBuffer ();
  return b;
}

00551 bool FLSqlCursor::next ()
{
  bool
      b =
      QSqlCursor::next ();

  refreshBuffer ();
  return b;
}

00561 bool FLSqlCursor::prev ()
{
  bool
      b =
      QSqlCursor::prev ();

  refreshBuffer ();
  return b;
}

00571 bool FLSqlCursor::first ()
{
  bool
      b =
      QSqlCursor::first ();

  refreshBuffer ();
  return b;
}

00581 bool FLSqlCursor::last ()
{
  bool
      b =
      QSqlCursor::last ();

  refreshBuffer ();
  return b;
}

int
00592 FLSqlCursor::del (bool invalidate)
{
  int r = QSqlCursor::del (invalidate);

  FLTableMetaData::FLFieldMetaDataList * fieldList = metadata_->fieldList ();
  FLFieldMetaData *field;

  for (unsigned int i = 0; i < fieldList->count (); i++)
      {
        field = fieldList->at (i);
        QString s = buffer_->value (field->name ()).toString ();

        FLFieldMetaData::FLRelationMetaDataList * relationList = field->relationList ();

        if (!relationList)
            continue;

        if (!relationList->isEmpty ())
            {
              FLRelationMetaData *r;

              for (unsigned int i = 0; i < relationList->count (); i++)
                  {
                    r = relationList->at (i);
                    FLSqlCursor c (r->foreignTable ());

                    FLFieldMetaData *f = c.metadata ()->field (r->foreignField ());
                    if (f->relationM1 ()->deleteCascade ())
                        {
                          c.select ("upper(" + r->foreignField () + ")=" + FLManager::formatValue (f, QVariant (s.upper ())));
                          while (c.next ())
                              {
                                c.primeDelete ();
                                c.del (false);
                              }
                        }
                  }
            }
      }

  return r;
}

void
00636 FLSqlCursor::setValueBuffer (const QString & fN, const QVariant & v)
{
  if (!buffer_ || fN.isEmpty () || !v.isValid ())
      return;

  buffer_->setValue (fN, v);

  emit bufferChanged (fN);
}

00646 QVariant FLSqlCursor::valueBuffer (const QString & fN) const
{
  if (!buffer_ || fN.isEmpty ())
      return QVariant ();

  return buffer_->value (fN);
}

void
00655 FLSqlCursor::deleteRecord ()
{
  openFormInMode (DEL);
}

void
00661 FLSqlCursor::browseRecord ()
{
  refresh ();
  openFormInMode (BROWSE);
}

void
00668 FLSqlCursor::editRecord ()
{
  refresh ();
  openFormInMode (EDIT);
}

void
00675 FLSqlCursor::insertRecord ()
{
  if (cursorRelation && relation && metadata_)
      {
        if (cursorRelation->modeAccess () == INSERT)
            {
              QString fG = cursorRelation->valueBuffer (relation->foreignField ()).toString ();
              if (!cursorRelation->commitBuffer ())
                  return;
              cursorRelation->setModeAccess (EDIT);
              cursorRelation->select ("upper(" + relation->field () + ")=" +
                                                  FLManager::formatValue (cursorRelation->metadata ()->field (relation->foreignField ()), QVariant (fG.upper ())));
              cursorRelation->seek (0);
              cursorRelation->QSqlCursor::select ("");
              cursorRelation->QSqlCursor::next ();
            }
      }
  openFormInMode (INSERT);
}

void
00696 FLSqlCursor::openFormInMode (int m, bool cont)
{
  if (!metadata_)
      return;

  if ((!isValid () || size () <= 0) && m != INSERT)
      {
        QMessageBox::warning (qApp->mainWidget (), tr ("Aviso"), tr ("No hay ningún registro seleccionado"), QMessageBox::Ok, 0, 0);

        return;
      }

  if (m == DEL)
      {
        int res = QMessageBox::information (qApp->mainWidget (),
                                                              tr ("Borrar registro"),
                                                              tr ("El registro activo será borrado. ¿ Está seguro ?"),
                                                              QMessageBox::Yes,
                                                              QMessageBox::No | QMessageBox::Default | QMessageBox::Escape);

        if (res == QMessageBox::No)
            return;

        modeAccess_ = DEL;
        refreshBuffer ();
        commitBuffer ();

        return;
      }

  QApplication::setOverrideCursor (Qt::WaitCursor);
  QString pathFormRecord = metadata ()->pathFormRecord ();

  if (pathFormRecord.isEmpty ())
      {
        QMessageBox::warning (qApp->mainWidget (), tr ("Aviso"),
                                          tr ("No hay definido ningún formulario para manejar ") + tr ("registros de esta tabla"), QMessageBox::Ok, 0, 0);
        QApplication::restoreOverrideCursor ();

        return;
      }

  modeAccess_ = m;
  if (buffer_)
      buffer_->clearValues (true);

  QWidget *w;
  FLReceiver *r = 0;
  if (!action_)
      action_ = FLManager::action (metadata_->name ());

  r = FLInterface::getReceiver (action_->process ());
  FLFormRecordDB *f = new FLFormRecordDB (this, qApp->mainWidget (), r,cont);

  if (r)
      w = QWidgetFactory::create (pathFormRecord, r, f);
  else
      w = QWidgetFactory::create (pathFormRecord, f, f);

  if (!w)
      {
        qWarning (tr ("FLSqlCursor : Ruta del formulario de edición '") +
                        pathFormRecord + tr ("' errónea. Ejecute 'make install' despues de compilar la aplicación."));
        QApplication::restoreOverrideCursor ();
        return;
      }
  
  f->setMainWidget (w);
  f->setFocus ();
  refreshBuffer ();
  f->show ();
  QApplication::restoreOverrideCursor ();
  updateBufferCopy();
}

void
00772 FLSqlCursor::setModeAccess (const int m)
{
  modeAccess_ = m;
}

void
00778 FLSqlCursor::chooseRecord ()
{
  if (edition)
      editRecord ();
  else if (browse)
      browseRecord ();

  emit recordChoosed ();
}

bool
00789 FLSqlCursor::fieldDisabled (const QString & fN)
{
  if (modeAccess_ == INSERT || modeAccess_ == EDIT)
      {
        if (cursorRelation && relation)
            return (relation->field ().lower () == fN.lower ());
        else
            return false;
      }
  else
      return false;
}

bool
00803 FLSqlCursor::transaction ()
{
  if (!QSqlDatabase::database ())
      {
        qWarning (tr ("FLSqlCursor::transaction() : No hay conexión con la base de datos"));
        return false;
      }

  if (transaction_ == 0)
      {
        ((FLApplication *) qApp)->statusHelpMsg (tr ("Iniciando transacción..."));
        if (QSqlDatabase::database ()->transaction ())
            {
              transaction_++;
              return true;
            }
        else
            {
              qWarning (tr ("FLSqlCursor : Fallo al intentar iniciar transacción"));
              return false;
            }
      }
  else
      {
        transaction_++;
        return true;
      }
}

bool
00833 FLSqlCursor::rollback ()
{
  if (!QSqlDatabase::database ())
      {
        qWarning (tr ("FLSqlCursor::rollback() : No hay conexión con la base de datos"));
        return false;
      }

  if ((modeAccess_ == INSERT || modeAccess_ == EDIT) && isModifiedBuffer())
      {
        int res = QMessageBox::information (qApp->mainWidget (),
                                                              tr ("Cancelar cambios"),
                                                              tr ("Todos los cambios efectuados en el formulario actual se cancelarán. ¿ Está seguro ?"),
                                                              QMessageBox::Yes,
                                                              QMessageBox::No | QMessageBox::Default | QMessageBox::Escape);

        if (res == QMessageBox::No)
            return false;
      }

  if (transaction_ > 0)
      transaction_--;
  else
      return true;

  if (transaction_ == 0)
      {
        ((FLApplication *) qApp)->statusHelpMsg (tr ("Deshaciendo transacción..."));
        if (QSqlDatabase::database ()->rollback ())
            {
              modeAccess_ = BROWSE;
              buffer_ = 0;
              return true;
            }
        else
            {
              qWarning (tr ("FLSqlCursor : Fallo al intentar deshacer transacción"));
              return false;
            }
      }
  else
      return true;
}

bool
00878 FLSqlCursor::commit ()
{
  if (!QSqlDatabase::database ())
      {
        qWarning (tr ("FLSqlCursor::commit() : No hay conexión con la base de datos"));
        return false;
      }

  emit cursorUpdated ();

  if (transaction_ > 0)
      transaction_--;
  else
      return true;

  if (transaction_ == 0)
      {
        ((FLApplication *) qApp)->statusHelpMsg (tr ("Terminando transacción..."));
        if (QSqlDatabase::database ()->commit ())
            {
              modeAccess_ = BROWSE;
              buffer_ = 0;
              return true;
            }
        else
            {
              qWarning (tr ("FLSqlCursor : Fallo al intentar terminar transacción"));
              return false;
            }
      }
  else
      return true;
}

void
00913 FLSqlCursor::setMainFilter (const QString & f)
{
  mainFilter_ = f;
  setFilter (f);
  QSqlCursor::select ();
  emit cursorUpdated ();
}

bool
00922 FLSqlCursor::select (const QString & filter, const QSqlIndex & sort)
{
  if (mainFilter_.isEmpty ())
      return QSqlCursor::select (filter, sort);
  else
      {
        if (filter.isEmpty ())
            return QSqlCursor::select (mainFilter_, sort);
        else
            return QSqlCursor::select (mainFilter_ + " AND " + filter, sort);
      }
}

void
00936 FLSqlCursor::setAction (FLAction * a)
{
  if (action_)
      delete action_;

  action_ = a;
}

void
00945 FLSqlCursor::updateBufferCopy()
{
      if (bufferCopy_)
                  delete bufferCopy_;
      bufferCopy_ = new QSqlRecord( *buffer_ );
}

bool
00953 FLSqlCursor::isModifiedBuffer()
{
      if (!buffer_ || !bufferCopy_)
            return false;

      for (uint i=0; i<buffer_->count(); i++)
            if (buffer_->value(i) != bufferCopy_->value(i))
                        return true;

      return false;
}


Generated by  Doxygen 1.6.0   Back to index