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