void tst_QVCard21Writer::testEncodeParameters_data() { QTest::addColumn< QMultiHash<QString, QString> >("parameters"); QTest::addColumn<QByteArray>("expected"); QMultiHash<QString,QString> parameters; QTest::newRow("No parameters") << parameters << QByteArray(""); parameters.insert(QStringLiteral("TYPE"), QString::fromLatin1("HOME")); QTest::newRow("One TYPE parameter") << parameters << QByteArray(";HOME"); // HOME should appear before VOICE because it is more "important" and some vCard // parsers may ignore everything after the first TYPE parameters.insert(QStringLiteral("TYPE"), QString::fromLatin1("VOICE")); QTest::newRow("Two TYPE parameters") << parameters << QByteArray(";HOME;VOICE"); parameters.clear(); parameters.insert(QStringLiteral("ENCODING"), QString::fromLatin1("8BIT")); QTest::newRow("One ENCODING parameter") << parameters << QByteArray(";ENCODING=8BIT"); parameters.insert(QString::fromLatin1("X-PARAM"),QString::fromLatin1("VALUE")); QTest::newRow("Two parameters") << parameters << QByteArray(";X-PARAM=VALUE;ENCODING=8BIT"); parameters.clear(); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("VOICE")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("CELL")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("MODEM")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("CAR")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("VIDEO")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("FAX")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("BBS")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("PAGER")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("HOME")); parameters.insert(QStringLiteral("TYPE"), QStringLiteral("WORK")); // Ensure CELL and FAX are at the front because they are "more important" and some vCard // parsers may ignore everything after the first TYPE // Ensure WORK and HOME come next. // Besides these conditions, there are no other ordering constraints. The data here is simply // what the writer produces (as dictated by its internal data structures). QTest::newRow("TYPE parameters order") << parameters << QByteArray(";CELL;FAX;WORK;HOME;MODEM;CAR;VIDEO;BBS;PAGER;VOICE"); }
void tst_QVCard30Writer::testEncodeParameters() { QByteArray encodedParameters; QBuffer buffer(&encodedParameters); mWriter->setDevice(&buffer); buffer.open(QIODevice::WriteOnly); QString typeParameterName(QString::fromAscii("TYPE")); QString encodingParameterName(QString::fromAscii("ENCODING")); // No parameters QMultiHash<QString,QString> parameters; mWriter->encodeParameters(parameters); QCOMPARE(encodedParameters, QByteArray("")); // One TYPE parameter parameters.insert(typeParameterName,QString::fromAscii("HOME")); mWriter->writeCrlf(); // so it doesn't start folding buffer.close(); encodedParameters.clear(); buffer.open(QIODevice::WriteOnly); mWriter->encodeParameters(parameters); QCOMPARE(encodedParameters, QByteArray(";TYPE=HOME")); // Two TYPE parameters parameters.insert(typeParameterName,QString::fromAscii("VOICE")); mWriter->writeCrlf(); // so it doesn't start folding buffer.close(); encodedParameters.clear(); buffer.open(QIODevice::WriteOnly); mWriter->encodeParameters(parameters); QCOMPARE(encodedParameters, QByteArray(";TYPE=VOICE,HOME")); // One ENCODING parameter parameters.clear(); parameters.insert(encodingParameterName,QString::fromAscii("8BIT")); mWriter->writeCrlf(); // so it doesn't start folding buffer.close(); encodedParameters.clear(); buffer.open(QIODevice::WriteOnly); mWriter->encodeParameters(parameters); QCOMPARE(encodedParameters, QByteArray(";ENCODING=8BIT")); // Two parameters parameters.insert(QString::fromAscii("X-PARAM"),QString::fromAscii("VALUE")); mWriter->writeCrlf(); // so it doesn't start folding buffer.close(); encodedParameters.clear(); buffer.open(QIODevice::WriteOnly); mWriter->encodeParameters(parameters); QCOMPARE(encodedParameters, QByteArray(";X-PARAM=VALUE;ENCODING=8BIT")); // Parameter with characters that require backslash escaping parameters.clear(); parameters.insert(QString::fromAscii("X-P;ARAM"),QString::fromAscii("VA,LUE")); mWriter->writeCrlf(); // so it doesn't start folding buffer.close(); encodedParameters.clear(); buffer.open(QIODevice::WriteOnly); mWriter->encodeParameters(parameters); QCOMPARE(encodedParameters, QByteArray(";X-P\\;ARAM=VA\\,LUE")); }
bool OsmAnd::MapRendererTiledSymbolsResource::uploadToGPU() { typedef std::pair< std::shared_ptr<MapSymbol>, std::shared_ptr<const GPUAPI::ResourceInGPU> > SymbolResourceEntry; bool ok; bool anyUploadFailed = false; const auto link_ = link.lock(); const auto collection = static_cast<MapRendererTiledSymbolsResourcesCollection*>(&link_->collection); // Unique QMultiHash< std::shared_ptr<GroupResources>, SymbolResourceEntry > uniqueUploaded; for (const auto& groupResources : constOf(_uniqueGroupsResources)) { for (const auto& symbol : constOf(groupResources->group->symbols)) { // Prepare data and upload to GPU std::shared_ptr<const GPUAPI::ResourceInGPU> resourceInGPU; ok = resourcesManager->uploadSymbolToGPU(symbol, resourceInGPU); // If upload have failed, stop if (!ok) { LogPrintf(LogSeverityLevel::Error, "Failed to upload unique symbol in %dx%d@%d tile", tileId.x, tileId.y, zoom); anyUploadFailed = true; break; } // Mark this symbol as uploaded uniqueUploaded.insert(groupResources, qMove(SymbolResourceEntry(symbol, resourceInGPU))); } if (anyUploadFailed) break; } // Shared QMultiHash< std::shared_ptr<GroupResources>, SymbolResourceEntry > sharedUploaded; QMultiHash< std::shared_ptr<GroupResources>, SymbolResourceEntry > sharedReferenced; for (const auto& groupResources : constOf(_referencedSharedGroupsResources)) { if (groupResources->group->symbols.isEmpty()) continue; // This check means "continue if shared symbols were uploaded by other resource" // This check needs no special handling, since all GPU resources work is done from same thread. if (!groupResources->resourcesInGPU.isEmpty()) { for (const auto& entryResourceInGPU : rangeOf(constOf(groupResources->resourcesInGPU))) { const auto& symbol = entryResourceInGPU.key(); auto& resourceInGPU = entryResourceInGPU.value(); sharedReferenced.insert(groupResources, qMove(SymbolResourceEntry(symbol, resourceInGPU))); } continue; } for (const auto& symbol : constOf(groupResources->group->symbols)) { // Prepare data and upload to GPU std::shared_ptr<const GPUAPI::ResourceInGPU> resourceInGPU; ok = resourcesManager->uploadSymbolToGPU(symbol, resourceInGPU); // If upload have failed, stop if (!ok) { LogPrintf(LogSeverityLevel::Error, "Failed to upload unique symbol in %dx%d@%d tile", tileId.x, tileId.y, zoom); anyUploadFailed = true; break; } // Mark this symbol as uploaded sharedUploaded.insert(groupResources, qMove(SymbolResourceEntry(symbol, resourceInGPU))); } if (anyUploadFailed) break; } // If at least one symbol failed to upload, consider entire tile as failed to upload, // and unload its partial GPU resources if (anyUploadFailed) { uniqueUploaded.clear(); sharedUploaded.clear(); return false; } // All resources have been uploaded to GPU successfully by this point, // so it's safe to walk across symbols and remove bitmaps: // Unique for (const auto& entry : rangeOf(constOf(uniqueUploaded))) { const auto& groupResources = entry.key(); const auto& symbol = entry.value().first; auto& resource = entry.value().second; // Unload GPU data from symbol, since it's uploaded already resourcesManager->releaseGpuUploadableDataFrom(symbol); // Add GPU resource reference _symbolToResourceInGpuLUT.insert(symbol, resource); #if OSMAND_LOG_MAP_SYMBOLS_TO_GPU_RESOURCES_MAP_CHANGES LogPrintf(LogSeverityLevel::Debug, "Inserted GPU resource %p for map symbol %p in %p (uploadToGPU-uniqueUploaded)", resource.get(), symbol.get(), this); #endif // OSMAND_LOG_MAP_SYMBOLS_TO_GPU_RESOURCES_MAP_CHANGES groupResources->resourcesInGPU.insert(qMove(symbol), qMove(resource)); } // Shared (uploaded) for (const auto& entry : rangeOf(constOf(sharedUploaded))) { const auto& groupResources = entry.key(); auto symbol = entry.value().first; auto& resource = entry.value().second; // Unload GPU data from symbol, since it's uploaded already resourcesManager->releaseGpuUploadableDataFrom(symbol); // Add GPU resource reference _symbolToResourceInGpuLUT.insert(symbol, resource); #if OSMAND_LOG_MAP_SYMBOLS_TO_GPU_RESOURCES_MAP_CHANGES LogPrintf(LogSeverityLevel::Debug, "Inserted GPU resource %p for map symbol %p in %p (uploadToGPU-sharedUploaded)", resource.get(), symbol.get(), this); #endif // OSMAND_LOG_MAP_SYMBOLS_TO_GPU_RESOURCES_MAP_CHANGES groupResources->resourcesInGPU.insert(qMove(symbol), qMove(resource)); } // Shared (referenced) for (const auto& entry : rangeOf(constOf(sharedReferenced))) { const auto& groupResources = entry.key(); auto symbol = entry.value().first; auto& resource = entry.value().second; // Add GPU resource reference _symbolToResourceInGpuLUT.insert(symbol, resource); #if OSMAND_LOG_MAP_SYMBOLS_TO_GPU_RESOURCES_MAP_CHANGES LogPrintf(LogSeverityLevel::Debug, "Inserted GPU resource %p for map symbol %p in %p (uploadToGPU-sharedReferenced)", resource.get(), symbol.get(), this); #endif // OSMAND_LOG_MAP_SYMBOLS_TO_GPU_RESOURCES_MAP_CHANGES } return true; }
void TcDatabase::loadEngine(const QString& filename) { m_sqls.clear(); if ( m_handle.isOpen() ) { if ( dbType() == SQLSERVER ) { // 取出存储过程名 QSqlQuery procedures_query = QSqlQuery(m_handle); QSqlQuery query = QSqlQuery(m_handle); if ( procedures_query.exec("exec sp_procedures_rowset2") ) { while(procedures_query.next()) { QSqlRecord procedures = procedures_query.record(); QSqlField fieldSchema = procedures.field("PROCEDURE_SCHEMA"); if ( fieldSchema.isValid() && fieldSchema.value() != "sys" ) { QSqlField field = procedures.field("PROCEDURE_NAME"); if ( field.isValid() ) { SQLContext cnt; QString procedureID = field.value().toString().toLower(); int index = procedureID.indexOf(";"); if ( index >= 0 ) { procedureID = procedureID.left(index); } cnt.id = procedureID; QString paramsLine; if ( query.exec("exec sp_procedure_params_rowset '"+procedureID+"'") ) { while(query.next()) { QSqlRecord paramField = query.record(); QSqlField paramName = paramField.field("PARAMETER_NAME"); QString pname = paramName.value().toString(); if ( pname.compare("@RETURN_VALUE", Qt::CaseInsensitive) != 0 ) { QSqlField paramType = paramField.field("TYPE_NAME"); pname.remove(0, 1); QString ptype = paramType.value().toString().toLower(); if ( ptype == "nvarchar" ) { ptype = "string"; } cnt.params.insert(pname, ptype); paramsLine += ", :" + pname; } } query.finish(); if ( ! paramsLine.isEmpty() ) { paramsLine.remove(0, 2); } } cnt.text = "exec " + procedureID + " " + paramsLine; m_sqls[procedureID] = cnt; Q_EMIT dbiLoading(m_sqls.count(), procedureID); } } } procedures_query.finish(); } }else if ( dbType() == MYSQL ) { // 取出存储过程名 QString sql = "SELECT `name`, `param_list`, `body`, `returns` FROM `mysql`.`proc` WHERE `language` = 'SQL' AND `db` = '"+dbName()+"';"; QSqlQuery query = QSqlQuery(m_handle); if ( query.exec(sql) ) { QSqlField field; while(query.next()) { QSqlRecord procedures = query.record(); QString param_line; SQLContext cnt; cnt.id = procedures.field("name").value().toString(); cnt.params = getParamList(param_line, procedures.field("param_list").value().toString()); cnt.text = "call " + cnt.id + "(" + param_line + ");"; //cnt.text = procedures.field("body").value().toString(); m_sqls[cnt.id] = cnt; Q_EMIT dbiLoading(m_sqls.count(), cnt.id); Q_EMIT dbiLoading(m_sqls.count(), cnt.text); } query.finish(); } }else if ( dbType() == POSTGRESQL ) { // 取出存储过程名 QSqlQuery storedproc_query = QSqlQuery(m_handle); QSqlQuery query = QSqlQuery(m_handle); if ( storedproc_query.exec("SELECT specific_name" " , routine_name" " FROM information_schema.routines" " WHERE specific_schema = 'public'" " AND routine_schema = 'public'" " AND routine_type = 'FUNCTION';") ) { while(storedproc_query.next()) { QSqlRecord storedprocs = storedproc_query.record(); QSqlField fieldspecific = storedprocs.field("specific_name"); QSqlField fieldsqlid = storedprocs.field("routine_name" ); if ( fieldspecific.isValid() && fieldsqlid.isValid() ) { SQLContext cnt; cnt.id = fieldsqlid.value().toString().toLower(); QString paramsLine; if ( query.exec("SELECT parameter_name" " , udt_name" " FROM information_schema.parameters" " WHERE specific_schema = 'public'" " AND specific_name = '"+fieldspecific.value().toString()+"'" " AND parameter_mode = 'IN'" " ORDER BY ordinal_position;") ) { while(query.next()) { QSqlRecord fields = query.record(); QSqlField paramName = fields.field("parameter_name"); QSqlField paramType = fields.field("udt_name" ); if ( paramName.isValid() && paramType.isValid() ) { cnt.params.insert(paramName.value().toString(), paramType.value().toString()); paramsLine += ", :" + paramName.value().toString(); } } query.finish(); if ( ! paramsLine.isEmpty() ) { paramsLine.remove(0, 2); } } cnt.text = "SELECT * FROM " + cnt.id + "(" + paramsLine + ");"; m_sqls[cnt.id] = cnt; Q_EMIT dbiLoading(m_sqls.count(), cnt.id); } } storedproc_query.finish(); } } } QStringList filenames; QDir dir(filename); if ( dir.exists() ) { filenames = dir.entryList(QStringList(), QDir::Files, QDir::Name); for( int i=0; i<filenames.count(); i++ ) { QString ddlfile = filenames.at(i); filenames[i] = dir.absolutePath() + QDir::separator() + ddlfile; } }else { QFileInfo sqlsInfo(filename); if ( sqlsInfo.exists() ) { filenames.append(filename); } } foreach(QString ddlfile, filenames) { QFile f(ddlfile); if ( f.open(QFile::Text | QFile::ReadOnly) ) { m_engineFile = ddlfile; QTextStream in(&f); int rdType = 0; QString sqlId; QString sqlText; QMultiHash<QString, QString> sqlParams; while(!in.atEnd()) { QString line = in.readLine().trimmed(); clearComment(line); if ( line.isEmpty() ) { }else if ( line.startsWith("SQL:", Qt::CaseInsensitive) ) { if ( ! sqlId.isEmpty() && ! sqlText.isEmpty() ) { sqlText.replace("@", ":"); SQLContext cnt; cnt.id = sqlId; cnt.text = sqlText; cnt.params = sqlParams; m_sqls[sqlId] = cnt; Q_EMIT dbiLoading(m_sqls.count(), sqlId); } sqlId = line.mid(4).trimmed().toLower(); sqlText.clear(); sqlParams.clear(); rdType = 1; }else if ( line.startsWith("Params:", Qt::CaseInsensitive) ) { rdType = 2; }else if ( ! sqlId.isEmpty() ) { switch(rdType) { case 1: sqlText += line + "\n"; break; case 2: { QString paramName; QString paramType = "string"; int pos; if ( (pos=line.indexOf(" ")) >0 ) { paramName = line.left(pos); line = line.remove(0, pos).trimmed(); if ( (pos=line.indexOf(" ")) >0 ) { paramType = line.left(pos); }else { paramType = line; } }else { paramName = line; } QChar c = paramName.at(0); if ( c == ':' || c == '@' ) { paramName.remove(0, 1); } sqlParams.insert(paramName, paramType.toLower()); break; } } } } f.close(); if ( ! sqlId.isEmpty() && ! sqlText.isEmpty() ) { SQLContext cnt; cnt.id = sqlId; cnt.text = sqlText; cnt.params = sqlParams; m_sqls[sqlId] = cnt; Q_EMIT dbiLoading(m_sqls.count(), sqlId); } } }