/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright © 2011-2015 ForgeRock AS. All rights reserved.
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://forgerock.org/license/CDDLv1.0.html
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at http://forgerock.org/license/CDDLv1.0.html
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*/
package org.forgerock.openidm.repo.jdbc;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.forgerock.json.JsonPointer;
import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.ConflictException;
import org.forgerock.json.resource.ForbiddenException;
import org.forgerock.json.resource.InternalServerErrorException;
import org.forgerock.json.resource.NotFoundException;
import org.forgerock.json.resource.PreconditionFailedException;
import org.forgerock.json.resource.ResourceResponse;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.util.query.QueryFilter;
public interface TableHandler {
/**
* Gets an object from the repository by identifier. The returned object is not validated
* against the current schema and may need processing to conform to an updated schema.
* <p>
* The object will contain metadata properties, including object identifier {@code _id},
* and object version {@code _rev} to enable optimistic concurrency
*
* @param fullId the qualified identifier of the object to retrieve from the object set.
* @param type is the qualifier of the object to retrieve
* @param localId the identifier without the qualifier of the object to retrieve
* @param connection
* @throws NotFoundException if the specified object could not be found.
* @throws SQLException if a DB failure was reported
* @throws IOException if a failure to convert the JSON model was reported
* @throws InternalServerErrorException if the operation failed because of a (possibly transient) failure
* @return the requested object.
*/
public abstract ResourceResponse read(String fullId, String type,
String localId, Connection connection)
throws SQLException, IOException, ResourceException;
/**
* Creates a new object in the object set.
* <p>
* This method sets the {@code _id} property to the assigned identifier for the object,
* and the {@code _rev} property to the revised object version (For optimistic concurrency)
*
* @param fullId the client-generated identifier to use, or {@code null} if server-generated identifier is requested.
* @param type
* @param localId
* @param obj the contents of the object to create in the object set.
* @param connection
* @throws NotFoundException if the specified id could not be resolved.
* @throws ForbiddenException if access to the object or object set is forbidden.
* @throws PreconditionFailedException if an object with the same ID already exists.
* @throws InternalServerErrorException if the operation failed because of a (possibly transient) failure
* @throws java.io.IOException
* @throws java.sql.SQLException
*/
public abstract void create(String fullId, String type, String localId,
Map<String, Object> obj, Connection connection)
throws SQLException, IOException, ResourceException;
/**
* Updates the specified object in the object set.
* <p>
* This implementation requires MVCC and hence enforces that clients state what revision they expect
* to be updating
*
* If successful, this method updates metadata properties within the passed object,
* including: a new {@code _rev} value for the revised object's version
*
* @param fullId the identifier of the object to be put, or {@code null} to request a generated identifier.
* @param type
* @param localId
* @param rev the version of the object to update; or {@code null} if not provided.
* @param obj the contents of the object to put in the object set.
* @param connection
* @throws ConflictException if version is required but is {@code null}.
* @throws ForbiddenException if access to the object is forbidden.
* @throws NotFoundException if the specified object could not be found.
* @throws PreconditionFailedException if version did not match the existing object in the set.
* @throws BadRequestException if the passed identifier is invalid
* @throws InternalServerErrorException if the operation failed because of a (possibly transient) failure
* @throws java.io.IOException
* @throws java.sql.SQLException
*/
public abstract void update(String fullId, String type, String localId,
String rev, Map<String, Object> obj, Connection connection)
throws SQLException, IOException, ResourceException;
/**
* Deletes the specified object from the object set.
*
* @param fullId the identifier of the object to be deleted.
* @param type
* @param localId
* @param rev the version of the object to delete or {@code null} if not provided.
* @param connection
* @throws NotFoundException if the specified object could not be found.
* @throws ForbiddenException if access to the object is forbidden.
* @throws ConflictException if version is required but is {@code null}.
* @throws PreconditionFailedException if version did not match the existing object in the set.
* @throws InternalServerErrorException if the operation failed because of a (possibly transient) failure
* @throws java.io.IOException
* @throws java.sql.SQLException
*/
public abstract void delete(String fullId, String type, String localId,
String rev, Connection connection)
throws SQLException, IOException, ResourceException;
/**
* Performs the query on the specified object and returns the associated results.
* <p>
* Queries are parametric; a set of named parameters is provided as the query criteria.
* The query result is a JSON object structure composed of basic Java types.
*
* The returned map is structured as follow:
* - The top level map contains meta-data about the query, plus an entry with the actual result records.
* - The <code>QueryConstants</code> defines the map keys, including the result records (QUERY_RESULT)
*
* @param type identifies the object to query.
* @param params the parameters of the query to perform.
* @param connection
* @return the query results, which includes meta-data and the result records in JSON object structure format.
* @throws NotFoundException if the specified object could not be found.
* @throws BadRequestException if the specified params contain invalid arguments, e.g. a query id that is not
* configured, a query expression that is invalid, or missing query substitution tokens.
* @throws ForbiddenException if access to the object or specified query is forbidden.
* @throws InternalServerErrorException if the operation failed because of a (possibly transient) failure
* @throws java.sql.SQLException
*/
public List<Map<String, Object>> query(String type, Map<String, Object> params, Connection connection)
throws SQLException, ResourceException;
/**
* Performs the command on the specified target and returns the number of affected objects
* <p>
* Commands are parametric; a set of named parameters is provided as the query criteria.
* The command returns the number of records altered/updated/deleted.
*
* @param type identifies the object to query.
* @param params the parameters of the query to perform.
* @param connection
* @return the number of records affected.
* @throws BadRequestException if the specified params contain invalid arguments, e.g. a query id that is not
* configured, a query expression that is invalid, or missing query substitution tokens.
* @throws ForbiddenException if access to the object or specified query is forbidden.
* @throws InternalServerErrorException if the operation failed because of a (possibly transient) failure
* @throws java.sql.SQLException
*/
public Integer command(String type, Map<String, Object> params, Connection connection)
throws SQLException, ResourceException;
/**
* Check if a given queryId exists in our set of known queries
*
* @param queryId Identifier for the query
*
* @return true if queryId is available
*/
public boolean queryIdExists(final String queryId);
/**
* Builds a raw query from the supplied filter.
*
* @param filter the query filter
* @param replacementTokens a map to store any replacement tokens
* @param params a map containing query parameters
* @return the raw query String
*/
public String renderQueryFilter(QueryFilter<JsonPointer> filter, Map<String, Object> replacementTokens, Map<String, Object> params);
/**
* Query if a given exception signifies a well known error type
*
* Allows table handlers to abstract database specific differences in reporting errors.
*
* @param ex The exception thrown by the database
* @param errorType the error type to test against
* @return true if the exception matches the error type passed
*/
public boolean isErrorType(SQLException ex, ErrorType errorType);
/**
* As whether a given exception should be retried
* @param ex the exception thrown by the database
* @param connection where the failure occured, used for additional context
* @return
*/
public boolean isRetryable(SQLException ex, Connection connection);
}