All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.appengine.api.datastore.DatastoreService Maven / Gradle / Ivy

There is a newer version: 2.0.32
Show newest version
/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.appengine.api.datastore;

import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;

// Note: Do not confuse this class with the class of the same name in
// com.google.apphosting.datastore, which is the *internal* Stubby
// *implementation* of the data service that is used by the appserver.
// This class is the *external* API that we present to user code,
// which simply forwards requests on to the appserver via ApiProxy.

// TODO that does not take a transaction should
// enlist the operation in the current transaction if the query is an ancestor.
// We have to wait for a major version upgrade to make this change otherwise
// we'll break existing apps that are running ancestor queries inside
// transactions that are associated with an entity group not equal to the
// entity group of the ancestor.

/**
 * The {@code DatastoreService} provides synchronous access to a schema-less data storage system.
 * The fundamental unit of data in this system is the {@code Entity}, which has an immutable
 * identity (represented by a {@code Key}) and zero or more mutable properties. {@code Entity}
 * objects can be created, updated, deleted, retrieved by identifier, and queried via a combination
 * of properties.
 *
 * 

The {@code DatastoreService} can be used transactionally and supports the notion of a * "current" transaction. A current transaction is established by calling {@link * #beginTransaction()}. The transaction returned by this method ceases to be current when an * attempt is made to commit or rollback or when another call is made to {@link * #beginTransaction()}. A transaction can only be current within the Thread that created it. * *

The various overloads of put, get, and delete all support transactions. Users of this class * have the choice of explicitly passing a (potentially {@code null}) {@link Transaction} to these * methods or relying on the behavior governed by the {@link ImplicitTransactionManagementPolicy}. * If a user explicitly provides a {@link Transaction} it is up to the user to call {@link * Transaction#commit()} or {@link Transaction#rollback()} at the proper time. If a user relies on * implicit transaction management and the installed policy creates a transaction, that transaction * will be committed (in the case of a success) or rolled back (in the case of a failure) before the * operation returns to the user. The methods that manage transactions according to {@link * ImplicitTransactionManagementPolicy} are: {@link #delete(Key...)}, {@link #delete(Iterable)}, * {@link #get(Key)}, {@link #get(Iterable)}, {@link #put(Entity)}, and {@link #put(Iterable)}. * *

The overload of prepare that takes a {@link Transaction} parameter behaves the same as the * overloads of put, get, and delete that take a {@link Transaction} parameter. However, the * overload of prepare that does not take a {@link Transaction} parameter, unlike put, get, and * delete, does not use an existing {@link Transaction} if one is already running and does not * consult the {@link ImplicitTransactionManagementPolicy} if one is not already running. */ public interface DatastoreService extends BaseDatastoreService { /** * Retrieves the {@code Entity} with the specified {@code Key}. * *

If there is a current transaction, this operation will execute within that transaction. In * this case it is up to the caller to commit or rollback. If there is no current transaction, the * behavior of this method with respect to transactions will be determined by the {@link * ImplicitTransactionManagementPolicy} available on the {@link DatastoreServiceConfig}. * * @throws EntityNotFoundException If the specified entity could not be found. * @throws IllegalArgumentException If the specified key is invalid. * @throws DatastoreFailureException If any other datastore error occurs. */ Entity get(Key key) throws EntityNotFoundException; /** * Exhibits the same behavior as {@link #get(Key)}, but executes within the provided transaction. * It is up to the caller to commit or rollback. Transaction can be null. * * @throws IllegalStateException If {@code txn} is not null and not active. */ Entity get(Transaction txn, Key key) throws EntityNotFoundException; /** * Retrieves the set of {@link Entity Entities} matching {@code keys}. The result {@code Map} will * only contain {@code Keys} for which {@code Entities} could be found. * *

If there is a current transaction, this operation will execute within that transaction. In * this case it is up to the caller to commit or rollback. If there is no current transaction, the * behavior of this method with respect to transactions will be determined by the {@link * ImplicitTransactionManagementPolicy} available on the {@link DatastoreServiceConfig}. * * @throws IllegalArgumentException If any {@code Key} in keys is invalid. * @throws DatastoreFailureException If any other datastore error occurs. */ Map get(Iterable keys); /** * Exhibits the same behavior as {@link #get(Iterable)}, but executes within the provided * transaction. It is up to the caller to commit or rollback. Transaction can be null. * * @throws IllegalStateException If {@code txn} is not null and not active. */ Map get(Transaction txn, Iterable keys); /** * If the specified {@code Entity} does not yet exist in the data store, create it and assign its * {@code Key}. If the specified {@code Entity} already exists in the data store, save the new * version. * *

The {@code Key} is returned, and is also returned by future calls to {@code * entity.getKey()}. * *

If there is a current transaction, this operation will execute within that transaction. In * this case it is up to the caller to commit or rollback. If there is no current transaction, the * behavior of this method with respect to transactions will be determined by the {@link * ImplicitTransactionManagementPolicy} available on the {@link DatastoreServiceConfig}. * * @throws IllegalArgumentException If the specified entity was incomplete. * @throws ConcurrentModificationException If the entity group to which the entity belongs was * modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ Key put(Entity entity); /** * Exhibits the same behavior as {@link #put(Entity)}, but executes within the provided * transaction. It is up to the caller to commit or rollback. Transaction can be null. * * @throws IllegalStateException If {@code txn} is not null and not active. * @throws ConcurrentModificationException If the entity group to which the entity belongs was * modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ Key put(Transaction txn, Entity entity); /** * Performs a batch {@link #put(Entity) put} of all {@code entities}. * *

If there is a current transaction, this operation will execute within that transaction. In * this case it is up to the caller to commit or rollback. If there is no current transaction, the * behavior of this method with respect to transactions will be determined by the {@link * ImplicitTransactionManagementPolicy} available on the {@link DatastoreServiceConfig}. * * @return The {@code Key}s that were assigned to the entities that were put. If the {@code * Iterable} that was provided as an argument has a stable iteration order the {@code Key}s in * the {@code List} we return are in that same order. If the {@code Iterable} that was * provided as an argument does not have a stable iteration order the order of the {@code * Key}s in the {@code List} we return is undefined. * @throws IllegalArgumentException If any entity is incomplete. * @throws ConcurrentModificationException If an entity group to which any provided entity belongs * was modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ List put(Iterable entities); /** * Exhibits the same behavior as {@link #put(Iterable)}, but executes within the provided * transaction. It is up to the caller to commit or rollback. Transaction can be null. * * @return The {@code Key}s that were assigned to the entities that were put. If the {@code * Iterable} that was provided as an argument has a stable iteration order the {@code Key}s in * the {@code List} we return are in that same order. If the {@code Iterable} that was * provided as an argument does not have a stable iteration order the order of the {@code * Key}s in the {@code List} we return is undefined. * @throws IllegalStateException If {@code txn} is not null and not active. * @throws ConcurrentModificationException If an entity group to which any provided entity belongs * was modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ List put(Transaction txn, Iterable entities); /** * Deletes the {@code Entity entities} specified by {@code keys}. * *

If there is a current transaction, this operation will execute within that transaction. In * this case it is up to the caller to commit or rollback. If there is no current transaction, the * behavior of this method with respect to transactions will be determined by the {@link * ImplicitTransactionManagementPolicy} available on the {@link DatastoreServiceConfig}. * * @throws IllegalArgumentException If the specified key was invalid. * @throws ConcurrentModificationException If an entity group to which any provided key belongs * was modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ void delete(Key... keys); /** * Exhibits the same behavior as {@link #delete(Key...)}, but executes within the provided * transaction. It is up to the caller to commit or rollback. Transaction can be null. * * @throws IllegalStateException If {@code txn} is not null and not active. * @throws ConcurrentModificationException If an entity group to which any provided key belongs * was modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ void delete(Transaction txn, Key... keys); /** * Equivalent to {@link #delete(Key...)}. * * @throws ConcurrentModificationException If an entity group to which any provided key belongs * was modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ void delete(Iterable keys); /** * Exhibits the same behavior as {@link #delete(Iterable)}, but executes within the provided * transaction. It is up to the caller to commit or rollback. Transaction can be null. * * @throws IllegalStateException If {@code txn} is not null and not active. * @throws ConcurrentModificationException If an entity group to which any provided key belongs * was modified concurrently. * @throws DatastoreFailureException If any other datastore error occurs. */ void delete(Transaction txn, Iterable keys); /** * Equivalent to {@code beginTransaction(TransactionOptions.Builder.withDefaults())}. * * @return the {@code Transaction} that was started. * @throws DatastoreFailureException If a datastore error occurs. * @see #beginTransaction(TransactionOptions) */ Transaction beginTransaction(); /** * Begins a transaction against the datastore. Callers are responsible for explicitly calling * {@link Transaction#commit()} or {@link Transaction#rollback()} when they no longer need the * {@code Transaction}. * *

The {@code Transaction} returned by this call will be considered the current transaction and * will be returned by subsequent, same-thread calls to {@link #getCurrentTransaction()} and * {@link #getCurrentTransaction(Transaction)} until one of the following happens: 1) {@link * #beginTransaction()} is invoked from the same thread. In this case {@link * #getCurrentTransaction()} and {@link #getCurrentTransaction(Transaction)} will return the * result of the more recent call to {@link #beginTransaction()}. 2) {@link Transaction#commit()} * is invoked on the {@link Transaction} returned by this method. Whether or not the commit * returns successfully, the {@code Transaction} will no longer be the current transaction. 3) * {@link Transaction#rollback()} ()} is invoked on the {@link Transaction} returned by this * method. Whether or not the rollback returns successfully, the {@code Transaction} will no * longer be the current transaction. * * @param options The options for the new transaction. * @return the {@code Transaction} that was started. * @throws DatastoreFailureException If a datastore error occurs. * @see #getCurrentTransaction() * @see TransactionOptions */ Transaction beginTransaction(TransactionOptions options); /** * IDs are allocated within a namespace defined by a parent key and a kind. This method allocates * a contiguous range of unique IDs of size {@code num} within the namespace defined by a null * parent key (root entities) and the given kind. * *

IDs allocated in this manner may be provided manually to newly created entities. They will * not be used by the datastore's automatic ID allocator for root entities of the same kind. * * @param kind The kind for which the root entity IDs should be allocated. * @param num The number of IDs to allocate. * @return A {@code KeyRange} of size {@code num}. * @throws IllegalArgumentException If {@code num} is less than 1 or if {@code num} is greater * than 1 billion. * @throws DatastoreFailureException If a datastore error occurs. */ KeyRange allocateIds(String kind, long num); /** * IDs are allocated within a namespace defined by a parent key and a kind. This method allocates * a contiguous range of unique IDs of size {@code num} within the namespace defined by the given * parent key and the given kind. * *

IDs allocated in this manner may be provided manually to newly created entities. They will * not be used by the datastore's automatic ID allocator for entities with the same kind and * parent. * * @param parent The key for which the child entity IDs should be allocated. Can be null. * @param kind The kind for which the child entity IDs should be allocated. * @param num The number of IDs to allocate. * @return A range of IDs of size {@code num} that are guaranteed to be unique. * @throws IllegalArgumentException If {@code parent} is not a complete key, if {@code num} is * less than 1, or if {@code num} is greater than 1 billion. * @throws DatastoreFailureException If a datastore error occurs. */ KeyRange allocateIds(Key parent, String kind, long num); /** * Indicates the state of a {@link KeyRange}. * * @see DatastoreService#allocateIdRange(KeyRange) */ enum KeyRangeState { /** * Indicates the given {@link KeyRange} is empty and the datastore's automatic ID allocator will * not assign keys in this range to new entities. */ EMPTY, /** * Indicates the given {@link KeyRange} is empty but the datastore's automatic ID allocator may * assign new entities keys in this range. However it is safe to manually assign {@link Key * Keys} in this range if either of the following is true: * *

    *
  • No other request will insert entities with the same kind and parent as the given {@link * KeyRange} until all entities with manually assigned keys from this range have been * written. *
  • Overwriting entities written by other requests with the same kind and parent as the * given {@link KeyRange} is acceptable. *
* *

The datastore's automatic ID allocator will not assign a key to a new entity that will * overwrite an existing entity, so once the range is populated there will no longer be any * contention. */ CONTENTION, /** * Indicates that entities with keys inside the given {@link KeyRange} already exist and writing * to this range will overwrite those entities. Additionally the implications of {@link * #CONTENTION} apply. If overwriting entities that exist in this range is acceptable it is safe * to use the given range. * *

The datastore's automatic ID allocator will never assign a key to a new entity that will * overwrite an existing entity so entities written by the user to this range will never be * overwritten by an entity with an automatically assigned key. */ COLLISION, } /** * This method allocates a user-specified contiguous range of unique IDs. * *

Once these IDs have been allocated they may be provided manually to newly created entities. * *

Since the datastore's automatic ID allocator will never assign a key to a new entity that * will cause an existing entity to be overwritten, entities written to the given {@link KeyRange} * will never be overwritten. However, writing entities with manually assigned keys in this range * may overwrite existing entities (or new entities written by a separate request) depending on * the {@link KeyRangeState} returned. * *

This method should only be used if you have an existing numeric id range that you want to * reserve, e.g. bulk loading entities that already have IDs. If you don't care about which IDs * you receive, use {@link #allocateIds} instead. * * @param range The key range to allocate. * @return The state of the id range allocated. * @throws DatastoreFailureException If a datastore error occurs. */ KeyRangeState allocateIdRange(KeyRange range); /** * Retrieves the current datastore's attributes. * * @return The attributes of the datastore used to fulfill requests. * @throws DatastoreFailureException If a datastore error occurs. */ DatastoreAttributes getDatastoreAttributes(); /** Returns the application indexes and their states. */ Map getIndexes(); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy