예제 #1
0
long ServicesDb::insertMap(QString displayName, int userId, bool publicVisibility)
{
  if (_insertMap == 0)
  {
    _insertMap.reset(new QSqlQuery(_db));
    _insertMap->prepare("INSERT INTO maps (display_name, user_id, public, created_at) "
                       "VALUES (:display_name, :user_id, :public, NOW()) "
                       "RETURNING id");
  }
  _insertMap->bindValue(":display_name", displayName);
  _insertMap->bindValue(":user_id", userId);
  _insertMap->bindValue(":public", publicVisibility);

  long mapId = _insertRecord(*_insertMap);

  QString mapIdStr = _getMapIdString(mapId);
  _copyTableStructure("changesets", _getChangesetsTableName(mapId));
  _copyTableStructure("current_nodes", "current_nodes" + mapIdStr);
  _copyTableStructure("current_relation_members", "current_relation_members" + mapIdStr);
  _copyTableStructure("current_relations", "current_relations" + mapIdStr);
  _copyTableStructure("current_way_nodes", "current_way_nodes" + mapIdStr);
  _copyTableStructure("current_ways", "current_ways" + mapIdStr);

  _execNoPrepare("CREATE SEQUENCE " + _getNodeSequenceName(mapId));
  _execNoPrepare("CREATE SEQUENCE " + _getRelationSequenceName(mapId));
  _execNoPrepare("CREATE SEQUENCE " + _getWaySequenceName(mapId));

  _execNoPrepare(QString("ALTER TABLE %1 "
    "ALTER COLUMN id SET DEFAULT NEXTVAL('%4'::regclass)")
      .arg(_getNodesTableName(mapId))
      .arg(_getNodeSequenceName(mapId)));

  _execNoPrepare(QString("ALTER TABLE %1 "
    "ALTER COLUMN id SET DEFAULT NEXTVAL('%4'::regclass)")
      .arg(_getRelationsTableName(mapId))
      .arg(_getRelationSequenceName(mapId)));

  _execNoPrepare(QString("ALTER TABLE %1 "
    "ALTER COLUMN id SET DEFAULT NEXTVAL('%4'::regclass)")
      .arg(_getWaysTableName(mapId))
      .arg(_getWaySequenceName(mapId)));

  // remove the index to speed up inserts. It'll be added back by createPendingMapIndexes
  _execNoPrepare(QString("DROP INDEX %1_tile_idx")
      .arg(_getNodesTableName(mapId)));

  _pendingMapIndexes.append(mapId);

  return mapId;
}
    StatusWith<RecordId> KVRecordStore::insertRecord(OperationContext* txn,
                                                     const char* data,
                                                     int len,
                                                     bool enforceQuota) {
        const RecordId id = _nextId();
        const Slice value(data, len);

        const Status status = _insertRecord(txn, id, value);
        if (!status.isOK()) {
            return StatusWith<RecordId>(status);
        }

        return StatusWith<RecordId>(id);
    }
예제 #3
0
StatusWith<RecordId> RecordStoreV1Base::insertRecord(OperationContext* txn,
                                                     const char* data,
                                                     int len,
                                                     bool enforceQuota) {
    if (len < 4) {
        return StatusWith<RecordId>(ErrorCodes::InvalidLength, "record has to be >= 4 bytes");
    }

    if (len + MmapV1RecordHeader::HeaderSize > MaxAllowedAllocation) {
        return StatusWith<RecordId>(ErrorCodes::InvalidLength, "record has to be <= 16.5MB");
    }

    return _insertRecord(txn, data, len, enforceQuota);
}
    StatusWith<DiskLoc> RecordStoreV1Base::insertRecord( OperationContext* txn,
                                                         const char* data,
                                                         int len,
                                                         bool enforceQuota ) {
        if ( len < 4 ) {
            return StatusWith<DiskLoc>( ErrorCodes::InvalidLength,
                                        "record has to be >= 4 bytes" );
        }

        StatusWith<DiskLoc> status = _insertRecord( txn, data, len, enforceQuota );
        if ( status.isOK() )
            _paddingFits( txn );

        return status;
    }
예제 #5
0
StatusWith<RecordId> RecordStoreV1Base::updateRecord(OperationContext* txn,
                                                     const RecordId& oldLocation,
                                                     const char* data,
                                                     int dataSize,
                                                     bool enforceQuota,
                                                     UpdateNotifier* notifier) {
    MmapV1RecordHeader* oldRecord = recordFor(DiskLoc::fromRecordId(oldLocation));
    if (oldRecord->netLength() >= dataSize) {
        // Make sure to notify other queries before we do an in-place update.
        if (notifier) {
            Status callbackStatus = notifier->recordStoreGoingToUpdateInPlace(txn, oldLocation);
            if (!callbackStatus.isOK())
                return StatusWith<RecordId>(callbackStatus);
        }

        // we fit
        memcpy(txn->recoveryUnit()->writingPtr(oldRecord->data(), dataSize), data, dataSize);
        return StatusWith<RecordId>(oldLocation);
    }

    // We enforce the restriction of unchanging capped doc sizes above the storage layer.
    invariant(!isCapped());

    // we have to move
    if (dataSize + MmapV1RecordHeader::HeaderSize > MaxAllowedAllocation) {
        return StatusWith<RecordId>(ErrorCodes::InvalidLength, "record has to be <= 16.5MB");
    }

    StatusWith<RecordId> newLocation = _insertRecord(txn, data, dataSize, enforceQuota);
    if (!newLocation.isOK())
        return newLocation;

    // insert worked, so we delete old record
    if (notifier) {
        Status moveStatus = notifier->recordStoreGoingToMove(
            txn, oldLocation, oldRecord->data(), oldRecord->netLength());
        if (!moveStatus.isOK())
            return StatusWith<RecordId>(moveStatus);
    }

    deleteRecord(txn, oldLocation);

    return newLocation;
}
    StatusWith<DiskLoc> RecordStoreV1Base::updateRecord( OperationContext* txn,
                                                         const DiskLoc& oldLocation,
                                                         const char* data,
                                                         int dataSize,
                                                         bool enforceQuota,
                                                         UpdateMoveNotifier* notifier ) {
        Record* oldRecord = recordFor( oldLocation );
        if ( oldRecord->netLength() >= dataSize ) {
            // we fit
            _paddingFits( txn );
            memcpy( txn->recoveryUnit()->writingPtr( oldRecord->data(), dataSize ), data, dataSize );
            return StatusWith<DiskLoc>( oldLocation );
        }

        if ( isCapped() )
            return StatusWith<DiskLoc>( ErrorCodes::InternalError,
                                        "failing update: objects in a capped ns cannot grow",
                                        10003 );

        // we have to move

        _paddingTooSmall( txn );

        StatusWith<DiskLoc> newLocation = _insertRecord( txn, data, dataSize, enforceQuota );
        if ( !newLocation.isOK() )
            return newLocation;

        // insert worked, so we delete old record
        if ( notifier ) {
            Status moveStatus = notifier->recordStoreGoingToMove( txn,
                                                                  oldLocation,
                                                                  oldRecord->data(),
                                                                  oldRecord->netLength() );
            if ( !moveStatus.isOK() )
                return StatusWith<DiskLoc>( moveStatus );
        }

        deleteRecord( txn, oldLocation );

        return newLocation;
    }
예제 #7
0
long ServicesDb::insertChangeSet(long mapId, long userId, const Tags& tags,
  geos::geom::Envelope env)
{
  _checkLastMapId(mapId);
  if (_insertChangeSet == 0)
  {
    _insertChangeSet.reset(new QSqlQuery(_db));
    _insertChangeSet->prepare(
      QString("INSERT INTO %1 (user_id, created_at, min_lat, max_lat, min_lon, max_lon, "
          "closed_at, tags) "
      "VALUES (:user_id, NOW(), :min_lat, :max_lat, :min_lon, :max_lon, NOW(), :tags) "
      "RETURNING id")
        .arg(_getChangesetsTableName(mapId)));
  }
  _insertChangeSet->bindValue(":user_id", (qlonglong)userId);
  _insertChangeSet->bindValue(":min_lat", env.getMinY());
  _insertChangeSet->bindValue(":max_lat", env.getMaxY());
  _insertChangeSet->bindValue(":min_lon", env.getMinX());
  _insertChangeSet->bindValue(":max_lon", env.getMaxX());
  _insertChangeSet->bindValue(":tags", _escapeTags(tags));

  return _insertRecord(*_insertChangeSet);
}
예제 #8
0
    StatusWith<RecordId> KVRecordStoreCapped::insertRecord( OperationContext* txn,
                                                           const char* data,
                                                           int len,
                                                           bool enforceQuota ) {
        if (len > _cappedMaxSize) {
            // this single document won't fit
            return StatusWith<RecordId>(ErrorCodes::BadValue,
                                       "object to insert exceeds cappedMaxSize");
        }

        StatusWith<RecordId> id(Status::OK());
        if (_isOplog) {
            id = oploghack::extractKey(data, len);
            if (!id.isOK()) {
                return id;
            }

            Status s = _insertRecord(txn, id.getValue(), Slice(data, len));
            if (!s.isOK()) {
                return StatusWith<RecordId>(s);
            }
        } else {
            // insert using the regular KVRecordStore insert implementation..
            id = KVRecordStore::insertRecord(txn, data, len, enforceQuota);
            if (!id.isOK()) {
                return id;
            }
        }

        _idTracker->addUncommittedId(txn, id.getValue());

        // ..then delete old data as needed
        deleteAsNeeded(txn);

        return id;
    }