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)); } }
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(); }
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()); }
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; } } }
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; }
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 }
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; }
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; }