void FLAccessControlTable::setFromObject(QObject *obj)
{
  FLTableMetaData *tm = ::qt_cast<FLTableMetaData *>(obj);
  if (!tm)
    return;

  if (acosPerms_) {
    acosPerms_->clear();
    delete acosPerms_;
  }

  acosPerms_ = new QDict < QString >(31);
  acosPerms_->setAutoDelete(true);

  const FLTableMetaData::FLFieldMetaDataList *fL = tm->fieldList();
  if (!fL)
    return;

  FLFieldMetaData *field;
  QChar permR, permW;
  QDictIterator<FLFieldMetaData> it(*fL);

  while ((field = it.current()) != 0) {
    ++it;
    permR = '-';
    permW = '-';
    if (field->visible())
      permR = 'r';
    if (field->editable())
      permW = 'w';
    acosPerms_->replace(field->name(), new QString(QString(permR) + permW));
  }
}
示例#2
0
QVariant FLUtil::nextCounter( const QString & name, FLSqlCursor * cursor_ ) {
  if ( !cursor_ )
    return QVariant();

  FLTableMetaData *tMD = cursor_->metadata();

  if ( !tMD )
    return QVariant();

  FLFieldMetaData *field = tMD->field( name );

  if ( !field )
    return QVariant();

  int type = field->type();

  if ( type != QVariant::String && type != QVariant::Double )
    return QVariant();

  unsigned int len = field->length();
  QString cadena;

  FLSqlQuery q( 0, cursor_->db()->connectionName() );
  q.setForwardOnly( true );
  q.setTablesList( tMD->name() );
  q.setSelect( name );
  q.setFrom( tMD->name() );
  q.setWhere( "LENGTH(" + name + ")=" + QString::number( len ) );
  q.setOrderBy( name + " DESC" );

  if ( !q.exec() )
    return QVariant();

  double maxRange = pow( 10, len );
  double numero = maxRange;

  while ( numero >= maxRange ) {
    if ( !q.next() ) {
      numero = 1;
      break;
    }
    numero = q.value( 0 ).toDouble();
    numero++;
  }

  if ( type == QVariant::String ) {
    cadena = QString::number( numero, 'f', 0 );
    if ( cadena.length() < len ) {
      QString str;
      str.fill( '0', ( len - cadena.length() ) );
      cadena = str + cadena;
    }
    return QVariant( cadena );
  }

  if ( type == QVariant::Double )
    return QVariant( numero );

  return QVariant();
}
示例#3
0
QString FLUtil::roundFieldValue(const QVariant &n, const QString &table, const QString &field)
{
  FLTableMetaData *tmd = FLSqlConnections::database()->manager()->metadata(table);
  if (!tmd)
    return 0;
  FLFieldMetaData *fmd = tmd->field(field);
  if (!fmd)
    return 0;
  return buildNumber(n, 'f', fmd->partDecimal());
}
示例#4
0
QSqlRecordInfo SqliteDriver::recordInfo(const QString &tablename) const
{
  QSqlRecordInfo info;
  if (!isOpen() || !dataBase_)
    return info;
  QDomDocument doc(tablename);
  QDomElement docElem;
  QString stream = db_->managerModules()->contentCached(tablename + ".mtd");
  if (!FLUtil::domDocumentSetContent(doc, stream)) {
#ifdef FL_DEBUG
    qWarning("FLManager : " + QApplication::tr("Error al cargar los metadatos para la tabla %1").arg(tablename));
#endif

    return recordInfo2(tablename);
  }
  docElem = doc.documentElement();
  FLTableMetaData *mtd = db_->manager()->metadata(&docElem, true);
  if (!mtd)
    return recordInfo2(tablename);
  FLTableMetaData::FLFieldMetaDataList *fl = mtd->fieldList();
  if (!fl) {
    delete mtd;
    return recordInfo2(tablename);
  }
  if (fl->isEmpty()) {
    delete mtd;
    return recordInfo2(tablename);
  }

  QStringList fieldsNames = QStringList::split(",", mtd->fieldsNames());
  for (QStringList::Iterator it = fieldsNames.begin(); it != fieldsNames.end(); ++it) {
    FLFieldMetaData *field = mtd->field((*it));
    info.append(QSqlFieldInfo(field->name(), FLFieldMetaData::flDecodeType(field->type())));
  }

  delete mtd;
  return info;
}
void FLAccessControlTable::processObject(QObject *obj)
{
  if (!obj || obj->aqWasDeleted())
    return;
  FLTableMetaData *tm = ::qt_cast<FLTableMetaData *>(obj);
  if (!tm)
    return;

  int maskPerm = 0;
  bool hasAcos = (acosPerms_ && !acosPerms_->isEmpty());

  if (!perm_.isEmpty()) {
    if (perm_.left(1) == "r")
      maskPerm |= 2;
    if (perm_.right(1) == "w")
      maskPerm |= 1;
  } else if (hasAcos)
    maskPerm = 8;
  else
    return;

  QString fieldPerm;
  QString *fieldPermPtr;
  int maskFieldPerm = 0;

  const FLTableMetaData::FLFieldMetaDataList *fL = tm->fieldList();
  if (!fL)
    return ;

  FLFieldMetaData *field;
  QDictIterator<FLFieldMetaData> it(*fL);

  while ((field = it.current()) != 0) {
    maskFieldPerm = maskPerm;
    ++it;

    if (hasAcos && (fieldPermPtr = (*acosPerms_)[ field->name()])) {
      fieldPerm = *fieldPermPtr;
      maskFieldPerm = 0;

      if (fieldPerm.left(1) == "r")
        maskFieldPerm |= 2;
      if (fieldPerm.right(1) == "w")
        maskFieldPerm |= 1;
    }

    switch (maskFieldPerm) {
      case 0:
        field->setVisible(false);
        field->setEditable(false);
        break;
      case 1:
        field->setVisible(false);
        field->setEditable(true);
        break;
      case 2:
        field->setVisible(true);
        field->setEditable(false);
        break;
      case 3:
        field->setVisible(true);
        field->setEditable(true);
        break;
    }
  }
}
示例#6
0
QString SqliteDriver::sqlCreateTable(FLTableMetaData *tmd)
{
#ifndef FL_QUICK_CLIENT
  if (!tmd)
    return QString::null;

  QString primaryKey(QString::null);
  QString sql = "CREATE TABLE " + tmd->name() + " (";

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

  unsigned int unlocks = 0;
  QDictIterator<FLFieldMetaData> it(*fieldList);
  while ((field = it.current()) != 0) {
    ++it;
    if (field->type() == FLFieldMetaData::Unlock)
      unlocks++;
  }
  if (unlocks > 1) {
#ifdef FL_DEBUG
    qWarning("FLManager : " + QApplication::tr("No se ha podido crear la tabla ") + tmd->name());
    qWarning("FLManager : " + QApplication::tr("Hay más de un campo tipo unlock. Solo puede haber uno."));
#endif

    return QString::null;
  }

  QDictIterator<FLFieldMetaData> it2(*fieldList);
  while ((field = it2.current()) != 0) {
    ++it2;
    sql += field->name();
    switch (field->type()) {
      case QVariant::Int:
        sql += " INTEGER";
        break;

      case QVariant::UInt:
        sql += " INTEGER";
        break;

      case QVariant::Bool:
      case FLFieldMetaData::Unlock:
        sql += " BOOLEAN";
        break;

      case QVariant::Double:
        sql += " FLOAT";
        break;

      case QVariant::Time:
        sql += " VARCHAR(20)";
        break;

      case QVariant::Date:
        sql += " VARCHAR(20)";
        break;

      case QVariant::Pixmap:
        sql += " TEXT";
        break;

      case QVariant::String:
        sql += " VARCHAR";
        break;

      case QVariant::StringList:
        sql += " TEXT";
        break;

      case QVariant::ByteArray:
        sql += " CLOB";
        break;

      case FLFieldMetaData::Serial:
        sql += " INTEGER";
        if (!field->isPrimaryKey())
          sql += " PRIMARY KEY";
        break;
    }

    int longitud = field->length();
    if (longitud > 0)
      sql += "(" + QString::number(longitud) + ")";

    if (field->isPrimaryKey()) {
      if (primaryKey.isEmpty()) {
        sql += " PRIMARY KEY";
        primaryKey = field->name();
      } else {
#ifdef FL_DEBUG
        qWarning(QApplication::tr("FLManager : Tabla -> ") +
                 tmd->name() + QApplication::tr(" . Se ha intentado poner una segunda clave primaria para el campo ") +
                 field->name() + QApplication::tr(" , pero el campo ") + primaryKey +
                 QApplication::tr(" ya es clave primaria. Sólo puede existir una clave primaria en FLTableMetaData, use FLCompoundKey para crear claves compuestas."));
#endif

        return QString::null;
      }
    } else {
      if (field->isUnique())
        sql += " UNIQUE";
      if (!field->allowNull())
        sql += " NOT NULL";
      else
        sql += " NULL";
    }

    if (it2.current())
      sql += ",";
  }

  sql += ");";

  QString createIndex = "CREATE INDEX " + tmd->name() + "_pkey ON " + tmd->name() + " (" + tmd->primaryKey() + ");";

  sql += createIndex;

  return sql;

#endif //FL_QUICK_CLIENT

  return QString::null;
}
示例#7
0
bool SqliteDriver::alterTable(const QString &mtd1, const QString &mtd2, const QString &key)
{
#ifndef FL_QUICK_CLIENT
  FLTableMetaData *oldMTD = 0;
  FLTableMetaData *newMTD = 0;
  QDomDocument doc("doc");
  QDomElement docElem;

  if (!FLUtil::domDocumentSetContent(doc, mtd1)) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Error al cargar los metadatos."));
#endif
  } else {
    docElem = doc.documentElement();
    oldMTD = db_->manager()->metadata(&docElem, true);
  }

  if (oldMTD && oldMTD->isQuery())
    return true;

  if (!FLUtil::domDocumentSetContent(doc, mtd2)) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Error al cargar los metadatos."));
#endif

    return false;
  } else {
    docElem = doc.documentElement();
    newMTD = db_->manager()->metadata(&docElem, true);
  }

  if (!oldMTD)
    oldMTD = newMTD;

  if (oldMTD->name() != newMTD->name()) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Los nombres de las tablas nueva y vieja difieren."));
#endif

    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  QString oldPK = oldMTD->primaryKey(), newPK = newMTD->primaryKey();
  if (oldPK != newPK) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Los nombres de las claves primarias difieren."));
#endif

    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  if (oldMTD->fieldType(oldPK) != newMTD->fieldType(newPK)) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Los tipos de las claves primarias difieren."));
#endif

    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  if (db_->manager()->checkMetaData(oldMTD, newMTD)) {
    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return true;
  }

  if (!db_->manager()->existsTable(oldMTD->name())) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("La tabla %1 antigua de donde importar los registros no existe.").arg(oldMTD->name()));
#endif

    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  FLTableMetaData::FLFieldMetaDataList *fieldList = oldMTD->fieldList();
  FLFieldMetaData *oldField = 0;

  if (!fieldList) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Los antiguos metadatos no tienen campos."));
#endif

    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  QString renameOld = oldMTD->name().left(6) + "alteredtable" + QDateTime::currentDateTime().toString("ddhhssz");

  if (!db_->dbAux()) {
    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  db_->dbAux() ->transaction();

  if (!key.isEmpty() && key.length() == 40) {
    QSqlCursor c("flfiles", true, db_->dbAux());
    c.setForwardOnly(true);
    QSqlRecord *buffer;
    c.setFilter("nombre='" + renameOld + ".mtd'");
    c.select();
    if (!c.next()) {
      buffer = c.primeInsert();
      buffer->setValue("nombre", renameOld + ".mtd");
      buffer->setValue("contenido", mtd1);
      buffer->setValue("sha", key);
      c.insert();
    }
  }

  QSqlQuery q(QString::null, db_->dbAux());

  if (!q.exec("CREATE TABLE " + renameOld + " AS SELECT * FROM " + oldMTD->name() + ";") || !q.exec("DROP TABLE " + oldMTD->name() + ";")) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("No se ha podido renombrar la tabla antigua."));
#endif

    db_->dbAux() ->rollback();
    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  if (!db_->manager()->createTable(newMTD)) {
    db_->dbAux() ->rollback();
    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  QSqlCursor oldCursor(renameOld, true, db_->dbAux());
  oldCursor.setMode(QSqlCursor::ReadOnly);
  QSqlCursor newCursor(newMTD->name(), true, db_->dbAux());
  newCursor.setMode(QSqlCursor::Insert);

  oldCursor.select();
  int totalSteps = oldCursor.size();
  QProgressDialog progress(QApplication::tr("Reestructurando registros para %1...").arg(newMTD->alias()), 0, totalSteps, qApp->focusWidget(), 0, true);
  progress.setCaption(QApplication::tr("Tabla modificada"));

  int step = 0;
  QSqlRecord *newBuffer;
  QString sequence;
  fieldList = newMTD->fieldList();
  FLFieldMetaData *newField = 0;

  if (!fieldList) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Los nuevos metadatos no tienen campos."));
#endif

    db_->dbAux() ->rollback();
    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  if (fieldList->isEmpty()) {
#ifdef FL_DEBUG
    qWarning("FLManager::alterTable : " + QApplication::tr("Los nuevos metadatos no tienen campos."));
#endif

    db_->dbAux() ->rollback();
    if ((oldMTD != newMTD) && oldMTD)
      delete oldMTD;
    if (newMTD)
      delete newMTD;
    return false;
  }

  QVariant v;
  bool ok = true;
  while (oldCursor.next()) {
    newBuffer = newCursor.primeInsert();

    QDictIterator<FLFieldMetaData> it(*fieldList);
    while ((newField = it.current()) != 0) {
      ++it;
      oldField = oldMTD->field(newField->name());
      if (!oldField || !oldCursor.field(oldField->name())) {
        if (!oldField)
          oldField = newField;
        v = newField->defaultValue();
        v.cast(FLFieldMetaData::flDecodeType(newField->type()));
      } else {
        v = oldCursor.value(newField->name());
        if ((!oldField->allowNull() || !newField->allowNull()) &&
            (v.isNull() || !v.isValid())) {
          QVariant defVal(newField->defaultValue());
          if (!defVal.isNull() && defVal.isValid())
            v = defVal;
        }
        if (!v.cast(newBuffer->value(newField->name()).type())) {
#ifdef FL_DEBUG
          qWarning("FLManager::alterTable : " +
                   QApplication::tr("Los tipos del campo %1 no son compatibles. Se introducirá un valor nulo.")
                   .arg(newField->name()));
#endif
        }
      }
      if ((!oldField->allowNull() || !newField->allowNull()) && (v.isNull() || !v.isValid())) {
        switch (oldField->type()) {
          case QVariant::Int:
          case FLFieldMetaData::Serial:
          case QVariant::UInt:
          case QVariant::Bool:
          case FLFieldMetaData::Unlock:
            v =  int(0);
            break;
          case QVariant::Double:
            v = double(0.0);
            break;
          case QVariant::Time:
            v = QTime::currentTime();
            break;
          case QVariant::Date:
            v = QDate::currentDate();
            break;
          default:
            v = QString("NULL").left(newField->length());
            break;
        }
      }
      newBuffer->setValue(newField->name(), v);
    }

    if (!newCursor.insert()) {
      ok = false;
      break;
    }
    progress.setProgress(++step);
  }

  progress.setProgress(totalSteps);

  if ((oldMTD != newMTD) && oldMTD)
    delete oldMTD;

  if (newMTD)
    delete newMTD;

  if (ok)
    db_->dbAux() ->commit();
  else {
    db_->dbAux() ->rollback();
    return false;
  }
#else

  return true;
#endif //FL_QUICK_CLIENT
}
示例#8
0
FLTableMetaData *FLManager::metadata(QDomElement *mtd, bool quick)
{
  if (!mtd)
    return 0;

  QString name, a, q;
  bool v = true, ed = true, cw = true, dl = false;

  QDomNode no = mtd->firstChild();

  while (!no.isNull()) {
    QDomElement e = no.toElement();
    if (!e.isNull()) {
      if (e.tagName() == "field") {
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "name") {
        name = e.text();
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "query") {
        q = e.text();
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "alias") {
        a = e.text().mid(30, e.text().length() - 32);
        a = FLUtil::translate("MetaData", a);
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "visible") {
        v = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "editable") {
        ed = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "concurWarn") {
        cw = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "detectLocks") {
        dl = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
    }
    no = no.nextSibling();
  }

  FLTableMetaData *tmd = new FLTableMetaData(name, a, q);
  FLCompoundKey *cK = 0;
  QStringList assocs;

  tmd->setConcurWarn(cw);
  tmd->setDetectLocks(dl);
  no = mtd->firstChild();

  while (!no.isNull()) {
    QDomElement e = no.toElement();
    if (!e.isNull()) {
      if (e.tagName() == "field") {
        FLFieldMetaData *f = metadataField(&e, v, ed);
        if (!tmd)
          tmd = new FLTableMetaData(name, a, q);
        tmd->addFieldMD(f);
        if (f->isCompoundKey()) {
          if (!cK)
            cK = new FLCompoundKey();
          cK->addFieldMD(f);
        }
        if (!f->associatedFieldName().isEmpty()) {
          assocs.append(f->associatedFieldName());
          assocs.append(f->associatedFieldFilterTo());
          assocs.append(f->name());
        }
        no = no.nextSibling();
        continue;
      }
    }
    no = no.nextSibling();
  }

  tmd->setCompoundKey(cK);
  QString aWith, aBy;

  for (QStringList::Iterator it = assocs.begin(); it != assocs.end(); ++it) {
    aWith = (*it);
    ++it;
    aBy = (*it);
    ++it;
    tmd->field((*it))->setAssociatedField(tmd->field(aWith), aBy);
  }

  if (!q.isEmpty() && !quick) {
    FLSqlQuery *qry = query(q, tmd);

    if (qry) {
      QStringList fL = qry->fieldList();
      QString table, field;
      QString fields = tmd->fieldsNames();

      for (QStringList::Iterator it = fL.begin(); it != fL.end(); ++it) {
        table = (*it).section('.', 0, 0);
        field = (*it).section('.', 1, 1);

        if (table == name || fields.contains(field.lower()))
          continue;

        FLTableMetaData *mtdAux = metadata(table, true);
        if (mtdAux) {
          FLFieldMetaData *fmtdAux = mtdAux->field(field);
          if (fmtdAux) {
            int typeAux = fmtdAux->type();
            if (typeAux == FLFieldMetaData::Serial)
              typeAux = QVariant::UInt;
            tmd->addFieldMD(new FLFieldMetaData(field, fmtdAux->alias(), true, false, typeAux, fmtdAux->length(),
                                                false, fmtdAux->visible(), fmtdAux->editable(), fmtdAux->partInteger(),
                                                fmtdAux->partDecimal(), false, false, false, QVariant(), false,
                                                QString::null, fmtdAux->visibleGrid(), true, false));
          }
        }
      }

      qry->deleteLater();
    }
  }

  FLAccessControlLists *acl = aqApp ->acl();
  if (acl)
    acl->process(tmd);
  return tmd;
}
示例#9
0
FLFieldMetaData *FLManager::metadataField(QDomElement *field, bool v, bool ed)
{
  if (!field)
    return 0;

  bool ck = false;
  QString n, a, ol, rX, assocBy, assocWith;
  bool aN = true, iPK = true, c = false, iNX = false, uNI = false, coun = false, oT = false, vG = true;
  int t = QVariant::Int, l = 0, pI = 4, pD = 0;
  QVariant dV = QVariant();

  QDomNode no = field->firstChild();

  while (!no.isNull()) {
    QDomElement e = no.toElement();
    if (!e.isNull()) {
      if (e.tagName() == "relation" || e.tagName() == "associated") {
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "name") {
        n = e.text();
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "alias") {
        a = e.text().mid(30, e.text().length() - 32);
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "null") {
        aN = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "pk") {
        iPK = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "type") {
        if (e.text() == "int")
          t = QVariant::Int;
        else if (e.text() == "uint")
          t = QVariant::UInt;
        else if (e.text() == "bool")
          t = QVariant::Bool;
        else if (e.text() == "double")
          t = QVariant::Double;
        else if (e.text() == "time")
          t = QVariant::Time;
        else if (e.text() == "date")
          t = QVariant::Date;
        else if (e.text() == "pixmap")
          t = QVariant::Pixmap;
        else if (e.text() == "bytearray")
          t = QVariant::ByteArray;
        else if (e.text() == "string")
          t = QVariant::String;
        else if (e.text() == "stringlist")
          t = QVariant::StringList;
        else if (e.text() == "unlock")
          t = FLFieldMetaData::Unlock;
        else if (e.text() == "serial")
          t = FLFieldMetaData::Serial;
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "length") {
        l = e.text().toInt();
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "regexp") {
        rX = e.text();
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "default") {
        if (e.text().contains("QT_TRANSLATE_NOOP"))
          dV = QVariant(e.text().mid(30, e.text().length() - 32));
        else
          dV = QVariant(e.text());
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "outtransaction") {
        oT = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "counter") {
        coun = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "calculated") {
        c = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "visible") {
        v = (e.text() == "true" && v);
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "visiblegrid") {
        vG = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "editable") {
        ed = (e.text() == "true" && ed);
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "partI") {
        pI = e.text().toInt();
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "partD") {
        pD = e.text().toInt();
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "index") {
        iNX = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "unique") {
        uNI = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "ck") {
        ck = (e.text() == "true");
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "optionslist") {
        ol = e.text();
        no = no.nextSibling();
        continue;
      }
    }
    no = no.nextSibling();
  }

  FLFieldMetaData *f = new FLFieldMetaData(n, FLUtil::translate("MetaData", a), aN, iPK, t, l, c, v, ed, pI, pD, iNX,
                                           uNI, coun, dV, oT, rX, vG, true, ck);

  if (!ol.isEmpty())
    f->setOptionsList(ol);

  no = field->firstChild();

  while (!no.isNull()) {
    QDomElement e = no.toElement();
    if (!e.isNull()) {
      if (e.tagName() == "relation") {
        f->addRelationMD(metadataRelation(&e));
        no = no.nextSibling();
        continue;
      }
      if (e.tagName() == "associated") {
        QDomNode noas = e.firstChild();
        while (!noas.isNull()) {
          QDomElement eas = noas.toElement();
          if (!eas.isNull()) {
            if (eas.tagName() == "with") {
              assocWith = eas.text();
              noas = noas.nextSibling();
              continue;
            }
            if (eas.tagName() == "by") {
              assocBy = eas.text();
              noas = noas.nextSibling();
              continue;
            }
          }
          noas = noas.nextSibling();
        }
        no = no.nextSibling();
        continue;
      }
    }
    no = no.nextSibling();
  }

  if (!assocWith.isEmpty() && !assocBy.isEmpty())
    f->setAssociatedField(assocWith, assocBy);

  return f;
}