Exemplo n.º 1
0
bool QgsMemoryProvider::addFeatures( QgsFeatureList & flist )
{
  // TODO: sanity checks of fields and geometries
  for ( QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it )
  {
    mFeatures[mNextFeatureId] = *it;
    QgsFeature& newfeat = mFeatures[mNextFeatureId];
    newfeat.setFeatureId( mNextFeatureId );
    it->setFeatureId( mNextFeatureId );

    // update spatial index
    if ( mSpatialIndex )
      mSpatialIndex->insertFeature( newfeat );

    mNextFeatureId++;
  }

  updateExtent();

  return true;
}
Exemplo n.º 2
0
bool QgsWFSProvider::addFeatures( QgsFeatureList &flist )
{
  //create <Transaction> xml
  QDomDocument transactionDoc;
  QDomElement transactionElem = createTransactionElement( transactionDoc );
  transactionDoc.appendChild( transactionElem );

  //find out typename from uri and strip namespace prefix
  QString tname = mShared->mURI.typeName();
  if ( tname.isNull() )
  {
    return false;
  }
  removeNamespacePrefix( tname );

  //Add the features
  QgsFeatureList::iterator featureIt = flist.begin();
  for ( ; featureIt != flist.end(); ++featureIt )
  {
    //Insert element
    QDomElement insertElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, "Insert" );
    transactionElem.appendChild( insertElem );

    QDomElement featureElem = transactionDoc.createElementNS( mApplicationNamespace, tname );

    QgsAttributes featureAttributes = featureIt->attributes();
    int nAttrs = featureAttributes.size();
    for ( int i = 0; i < nAttrs; ++i )
    {
      const QVariant& value = featureAttributes.at( i );
      if ( value.isValid() && !value.isNull() )
      {
        QDomElement fieldElem = transactionDoc.createElementNS( mApplicationNamespace, mShared->mFields.at( i ).name() );
        QDomText fieldText = transactionDoc.createTextNode( value.toString() );
        fieldElem.appendChild( fieldText );
        featureElem.appendChild( fieldElem );
      }
    }

    //add geometry column (as gml)
    const QgsGeometry* geometry = featureIt->constGeometry();
    if ( geometry != nullptr )
    {
      QDomElement geomElem = transactionDoc.createElementNS( mApplicationNamespace, mShared->mGeometryAttribute );
      QgsGeometry the_geom( *geometry );
      // convert to multi if the layer geom type is multi and the geom is not
      if ( QGis::isMultiType( this->geometryType( ) ) && ! the_geom.isMultipart( ) )
      {
        the_geom.convertToMultiType();
      }
      QDomElement gmlElem = QgsOgcUtils::geometryToGML( &the_geom, transactionDoc );
      if ( !gmlElem.isNull() )
      {
        gmlElem.setAttribute( "srsName", crs().authid() );
        geomElem.appendChild( gmlElem );
        featureElem.appendChild( geomElem );
      }
    }

    insertElem.appendChild( featureElem );
  }

  QDomDocument serverResponse;
  bool success = sendTransactionDocument( transactionDoc, serverResponse );
  if ( !success )
  {
    return false;
  }

  if ( transactionSuccess( serverResponse ) )
  {
    //transaction successful. Add the features to the cache
    QStringList idList = insertedFeatureIds( serverResponse );
    QStringList::const_iterator idIt = idList.constBegin();
    featureIt = flist.begin();

    QVector<QgsWFSFeatureGmlIdPair> serializedFeatureList;
    for ( ; idIt != idList.constEnd() && featureIt != flist.end(); ++idIt, ++featureIt )
    {
      serializedFeatureList.push_back( QgsWFSFeatureGmlIdPair( *featureIt, *idIt ) );
    }
    mShared->serializeFeatures( serializedFeatureList );

    // And now set the feature id from the one got from the database
    QMap< QString, QgsFeatureId > map;
    for ( int idx = 0; idx < serializedFeatureList.size(); idx++ )
      map[ serializedFeatureList[idx].second ] = serializedFeatureList[idx].first.id();

    idIt = idList.constBegin();
    featureIt = flist.begin();
    for ( ; idIt != idList.constEnd() && featureIt != flist.end(); ++idIt, ++featureIt )
    {
      if ( map.find( *idIt ) != map.end() )
        featureIt->setFeatureId( map[*idIt] );
    }

    return true;
  }
  else
  {
    handleException( serverResponse );
    return false;
  }
}
Exemplo n.º 3
0
bool QgsDb2Provider::addFeatures( QgsFeatureList & flist )
{
  QgsDebugMsg( "mGeometryColType: " + mGeometryColType );
  int writeCount = 0;
  bool copyOperation = false;

  if ( !mDatabase.isOpen() )
  {
    QString errMsg;
    mDatabase = getDatabase( mConnInfo, errMsg );
    if ( !errMsg.isEmpty() )
    {
      QgsDebugMsg( "getDatabase failed: " + errMsg );
      return false;
    }
  }
  if ( !mDatabase.transaction() )
  {
    QgsDebugMsg( "transaction failed" );
    return false;
  }
  QSqlQuery query = QSqlQuery( mDatabase );
  query.setForwardOnly( true );
  QSqlQuery queryFid = QSqlQuery( mDatabase );
  queryFid.setForwardOnly( true );

  QgsFeature it = flist.at( 0 );
  QString statement;
  QString values;
  statement = QString( "INSERT INTO %1.%2 (" ).arg( mSchemaName, mTableName );

  bool first = true;

// Get the first geometry and its wkbType as when we are doing drag/drop,
// the wkbType is not passed to the DB2 provider from QgsVectorLayerImport
// Can't figure out how to resolved "unreferenced" wkbType compile message
// Don't really do anything with it at this point
#if 0
  QgsGeometry *geom = it.geometry();
  QgsWkbTypes::Type wkbType = geom->wkbType();
  QgsDebugMsg( QString( "wkbType: %1" ).arg( wkbType ) );
  QgsDebugMsg( QString( "mWkbType: %1" ).arg( mWkbType ) );
#endif

  QgsAttributes attrs = it.attributes();
  QgsDebugMsg( QString( "attrs.count: %1" ).arg( attrs.count() ) );
  QgsDebugMsg( QString( "fields.count: %1" ).arg( mAttributeFields.count() ) );
  if ( mAttributeFields.count() == ( attrs.count() + 1 ) )
  {
    copyOperation = true; // FID is first field but no attribute in attrs
  }
  else if ( mAttributeFields.count() !=  attrs.count() )
  {
    QgsDebugMsg( "Count mismatch - failing" );
    return false;
  }


  if ( attrs.count() != mAttributeFields.count() )
  {
    QgsDebugMsg( "field counts don't match" );
//  return false;
  }

  for ( int i = 0; i < mAttributeFields.count(); ++i )
  {
    QgsField fld = mAttributeFields.at( i );
    QgsDebugMsg( QString( "i: %1; got field: %2" ).arg( i ).arg( fld.name() ) );

    if ( fld.name().isEmpty() )
      continue; // invalid

    if ( mFidColName == fld.name() )
      continue; // skip identity field

//      if ( mDefaultValues.contains( i ) && mDefaultValues[i] == attrs.at( i ) )
//        continue; // skip fields having default values

    if ( !first )
    {
      statement += ',';
      values += ',';
    }
    else
      first = false;

    statement += QString( "%1" ).arg( fld.name() );
    values += QString( "?" );
  }

  // append geometry column name
  if ( !mGeometryColName.isEmpty() )
  {
    if ( !first )
    {
      statement += ',';
      values += ',';
    }

    statement += QString( "%1" ).arg( mGeometryColName );

    values += QString( "db2gse.%1(CAST (%2 AS BLOB(2M)),%3)" )
              .arg( mGeometryColType,
                    QString( "?" ),
                    QString::number( mSRId ) );
  }

  QgsDebugMsg( statement );
  QgsDebugMsg( values );
  statement += ") VALUES (" + values + ')';
  QgsDebugMsg( statement );

  QgsDebugMsg( "Prepare statement" );
  // use prepared statement to prevent from sql injection
  if ( !query.prepare( statement ) )
  {
    QString msg = query.lastError().text();
    QgsDebugMsg( msg );
    pushError( msg );
    return false;
  }


  for ( QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it )
  {
    attrs = it->attributes();

    int fieldIdx = 0;
    if ( copyOperation )
    {
      fieldIdx = 1;  // skip first (FID) field if copying from shapefile
    }
    int bindIdx = 0;
    for ( int i = 0; i < attrs.count(); i++ )
    {
      QgsField fld = mAttributeFields.at( fieldIdx++ );
      if ( fld.name().isEmpty() )
        continue; // invalid

      if ( mFidColName == fld.name() )
        continue; // skip identity field

//      if ( mDefaultValues.contains( i ) && mDefaultValues[i] == attrs.at( i ) )
//        continue; // skip fields having default values

      QVariant::Type type = fld.type();
      if ( attrs.at( i ).isNull() || !attrs.at( i ).isValid() )
      {
        // binding null values
        if ( type == QVariant::Date || type == QVariant::DateTime )
          query.bindValue( bindIdx,  QVariant( QVariant::String ) );
        else
          query.bindValue( bindIdx,  QVariant( type ) );
      }
      else if ( type == QVariant::Int )
      {
        // binding an INTEGER value
        query.bindValue( bindIdx,  attrs.at( i ).toInt() );
      }
      else if ( type == QVariant::Double )
      {
        // binding a DOUBLE value
        query.bindValue( bindIdx,  attrs.at( i ).toDouble() );
      }
      else if ( type == QVariant::String )
      {
        // binding a TEXT value
        query.bindValue( bindIdx,  attrs.at( i ).toString() );
      }
      else if ( type == QVariant::Time )
      {
        // binding a TIME value
        query.bindValue( bindIdx,  attrs.at( i ).toTime().toString( Qt::ISODate ) );
      }
      else if ( type == QVariant::Date )
      {
        // binding a DATE value
        query.bindValue( bindIdx,  attrs.at( i ).toDate().toString( Qt::ISODate ) );
      }
      else if ( type == QVariant::DateTime )
      {
        // binding a DATETIME value
        query.bindValue( bindIdx,  attrs.at( i ).toDateTime().toString( Qt::ISODate ) );
      }
      else
      {
        query.bindValue( bindIdx,  attrs.at( i ) );
      }

#if 0
      QgsDebugMsg( QString( "bound i: %1; name: %2; value: %3; bindIdx: %4" ).
                   arg( i ).arg( fld.name() ).arg( attrs.at( i ).toString() ).arg( bindIdx ) );
#endif
      bindIdx++;
    }

    if ( !mGeometryColName.isEmpty() )
    {
      QgsGeometry geom = it->geometry();

      QByteArray bytea = QByteArray(( char* )geom.asWkb(), ( int ) geom.wkbSize() );
      query.bindValue( bindIdx,  bytea, QSql::In | QSql::Binary );
    }

    QList<QVariant> list = query.boundValues().values();

// Show bound values
#if 0
    for ( int i = 0; i < list.size(); ++i )
    {
      QgsDebugMsg( QString( "i: %1; value: %2; type: %3" )
                   .arg( i ).arg( list.at( i ).toString().toLatin1().data() ).arg( list.at( i ).typeName() ) );
    }
#endif
    if ( !query.exec() )
    {
      QString msg = query.lastError().text();
      QgsDebugMsg( msg );
      if ( !mSkipFailures )
      {
        pushError( msg );
        return false;
      }
    }

    statement = QString( "select IDENTITY_VAL_LOCAL() AS IDENTITY "
                         "FROM SYSIBM.SYSDUMMY1" );
//    QgsDebugMsg( statement );
    if ( !queryFid.exec( statement ) )
    {
      QString msg = query.lastError().text();
      QgsDebugMsg( msg );
      if ( !mSkipFailures )
      {
        pushError( msg );
        return false;
      }
    }

    if ( !queryFid.next() )
    {
      QString msg = query.lastError().text();
      QgsDebugMsg( msg );
      if ( !mSkipFailures )
      {
        pushError( msg );
        return false;
      }
    }
    it->setFeatureId( queryFid.value( 0 ).toLongLong() );
    writeCount++;
//    QgsDebugMsg( QString( "count: %1; featureId: %2" ).arg( writeCount ).arg( queryFid.value( 0 ).toLongLong() ) );
  }
  bool commitStatus = mDatabase.commit();
  QgsDebugMsg( QString( "commitStatus: %1; write count: %2; featureId: %3" )
               .arg( commitStatus ).arg( writeCount ).arg( queryFid.value( 0 ).toLongLong() ) );
  if ( !commitStatus )
  {
    pushError( "Commit of new features failed" );
    return false;
  }
  return true;
}