Search in sources :

Example 16 with Row

use of io.vertx.sqlclient.Row in project raml-module-builder by folio-org.

the class PgUtil method collection.

private static <T, C> C collection(Class<T> clazz, Class<C> collectionClazz, RowSet<Row> resultSet, int offset, int limit) throws ReflectiveOperationException, IOException {
    int totalRecords = 0;
    int resultSize = resultSet.size();
    List<T> recordList = new ArrayList<>(resultSize);
    RowIterator<Row> iterator = resultSet.iterator();
    while (iterator.hasNext()) {
        Row row = iterator.next();
        String jsonb = row.getValue(JSON_COLUMN).toString();
        recordList.add(OBJECT_MAPPER.readValue(jsonb, clazz));
        totalRecords = row.getInteger(PostgresClient.COUNT_FIELD);
    }
    totalRecords = PostgresClient.getTotalRecords(resultSize, totalRecords, offset, limit);
    return collection(collectionClazz, recordList, totalRecords);
}
Also used : ArrayList(java.util.ArrayList) Row(io.vertx.sqlclient.Row)

Example 17 with Row

use of io.vertx.sqlclient.Row in project raml-module-builder by folio-org.

the class PgUtil method postSync.

/**
 * Post a list of T entities to the database. Fail all if any of them fails.
 * @param table database table to store into
 * @param entities  the records to store
 * @param maxEntities  fail with HTTP 413 if entities.size() > maxEntities to avoid out of memory;
 *     suggested value is from 100 ... 10000.
 * @param upsert  true to update records with the same id, false to fail all entities if one has an existing id
 * @param okapiHeaders  http headers provided by okapi
 * @param vertxContext  the current context
 * @param responseClass  the ResponseDelegate class created from the RAML file with these methods:
 *               respond201(), respond409WithTextPlain(Object), respond413WithTextPlain(Object), respond500WithTextPlain(Object).
 * @return future where to return the result created by responseClass
 */
public static <T> Future<Response> postSync(String table, List<T> entities, int maxEntities, boolean upsert, Map<String, String> okapiHeaders, Context vertxContext, Class<? extends ResponseDelegate> responseClass) {
    final Method respond500;
    try {
        respond500 = responseClass.getMethod(RESPOND_500_WITH_TEXT_PLAIN, Object.class);
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        return response(e.getMessage(), null, null);
    }
    try {
        Method respond201 = responseClass.getMethod(RESPOND_201);
        Method respond409 = getRespond409(responseClass);
        Method respond413 = responseClass.getMethod(RESPOND_413_WITH_TEXT_PLAIN, Object.class);
        if (entities != null && entities.size() > maxEntities) {
            String message = "Expected a maximum of " + maxEntities + " records to prevent out of memory but got " + entities.size();
            return response(message, respond413, respond500);
        }
        // RestVerticle populates a single record only, not an array of records
        Promise<Response> promise = Promise.promise();
        MetadataUtil.populateMetadata(entities, okapiHeaders);
        PostgresClient postgresClient = postgresClient(vertxContext, okapiHeaders);
        Handler<AsyncResult<RowSet<Row>>> replyHandler = result -> {
            if (result.failed()) {
                if (PgExceptionUtil.isVersionConflict(result.cause())) {
                    Method method = respond409 == null ? respond500 : respond409;
                    response(result.cause().getMessage(), method, respond500).onComplete(promise);
                } else {
                    response(table, /* id */
                    "", result.cause(), responseClass, respond500, respond500).onComplete(promise);
                }
            }
            response(respond201, respond500).onComplete(promise);
        };
        if (upsert) {
            postgresClient.upsertBatch(table, entities, replyHandler);
        } else {
            postgresClient.saveBatch(table, entities, replyHandler);
        }
        return promise.future();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        return response(e.getMessage(), respond500, respond500);
    }
}
Also used : Response(javax.ws.rs.core.Response) HttpServerResponse(io.vertx.core.http.HttpServerResponse) ValidationHelper(org.folio.rest.tools.utils.ValidationHelper) RoutingContext(io.vertx.ext.web.RoutingContext) Context(io.vertx.core.Context) MetadataUtil(org.folio.rest.tools.utils.MetadataUtil) RowIterator(io.vertx.sqlclient.RowIterator) Matcher(java.util.regex.Matcher) ObjectMapperTool(org.folio.dbschema.ObjectMapperTool) Map(java.util.Map) Method(java.lang.reflect.Method) Errors(org.folio.rest.jaxrs.model.Errors) CQLSortNode(org.z3950.zing.cql.CQLSortNode) FacetManager(org.folio.rest.persist.facets.FacetManager) HttpHeaders(io.vertx.core.http.HttpHeaders) UUID(java.util.UUID) FieldException(org.folio.cql2pgjson.exception.FieldException) Future(io.vertx.core.Future) TenantTool(org.folio.rest.tools.utils.TenantTool) InvocationTargetException(java.lang.reflect.InvocationTargetException) OutStream(org.folio.rest.tools.utils.OutStream) CQL2PgJSON(org.folio.cql2pgjson.CQL2PgJSON) List(java.util.List) Logger(org.apache.logging.log4j.Logger) CQLParser(org.z3950.zing.cql.CQLParser) Response(javax.ws.rs.core.Response) HttpServerResponse(io.vertx.core.http.HttpServerResponse) Pattern(java.util.regex.Pattern) CQLNode(org.z3950.zing.cql.CQLNode) ModifierSet(org.z3950.zing.cql.ModifierSet) Json(io.vertx.core.json.Json) CQLWrapper(org.folio.rest.persist.cql.CQLWrapper) FacetField(org.folio.rest.persist.facets.FacetField) CQLDefaultNodeVisitor(org.z3950.zing.cql.CQLDefaultNodeVisitor) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) UuidUtil(org.folio.util.UuidUtil) ResultInfo(org.folio.rest.jaxrs.model.ResultInfo) ArrayList(java.util.ArrayList) ResponseDelegate(org.folio.rest.jaxrs.resource.support.ResponseDelegate) QueryValidationException(org.folio.cql2pgjson.exception.QueryValidationException) CQLParseException(org.z3950.zing.cql.CQLParseException) RowSet(io.vertx.sqlclient.RowSet) AsyncResult(io.vertx.core.AsyncResult) CQLFeatureUnsupportedException(org.folio.cql2pgjson.exception.CQLFeatureUnsupportedException) Diagnostic(org.folio.rest.jaxrs.model.Diagnostic) Modifier(org.z3950.zing.cql.Modifier) Promise(io.vertx.core.Promise) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) Row(io.vertx.sqlclient.Row) Handler(io.vertx.core.Handler) LogManager(org.apache.logging.log4j.LogManager) Method(java.lang.reflect.Method) Row(io.vertx.sqlclient.Row) AsyncResult(io.vertx.core.AsyncResult) FieldException(org.folio.cql2pgjson.exception.FieldException) InvocationTargetException(java.lang.reflect.InvocationTargetException) QueryValidationException(org.folio.cql2pgjson.exception.QueryValidationException) CQLParseException(org.z3950.zing.cql.CQLParseException) CQLFeatureUnsupportedException(org.folio.cql2pgjson.exception.CQLFeatureUnsupportedException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException)

Example 18 with Row

use of io.vertx.sqlclient.Row in project raml-module-builder by folio-org.

the class PostgresClient method executeGetQuery.

private <T> void executeGetQuery(PgConnection connection, QueryHelper queryHelper, ResultInfo resultInfo, Class<T> clazz, Handler<AsyncResult<PostgresClientStreamResult<T>>> replyHandler, Transaction transaction) {
    connection.prepare(queryHelper.selectQuery, prepareRes -> {
        if (prepareRes.failed()) {
            closeIfNonNull(transaction).onComplete(ignore -> {
                log.error(prepareRes.cause().getMessage(), prepareRes.cause());
                replyHandler.handle(Future.failedFuture(prepareRes.cause()));
            });
            return;
        }
        PreparedStatement preparedStatement = prepareRes.result();
        RowStream<Row> rowStream = new PreparedRowStream(preparedStatement, STREAM_GET_DEFAULT_CHUNK_SIZE, Tuple.tuple());
        PostgresClientStreamResult<T> streamResult = new PostgresClientStreamResult<>(resultInfo);
        doStreamRowResults(rowStream, clazz, transaction, queryHelper, streamResult, replyHandler);
    });
}
Also used : PreparedStatement(io.vertx.sqlclient.PreparedStatement) Row(io.vertx.sqlclient.Row)

Example 19 with Row

use of io.vertx.sqlclient.Row in project raml-module-builder by folio-org.

the class AdminAPI method putAdminPostgresDropIndexes.

@Validate
@Override
public void putAdminPostgresDropIndexes(Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
    String schema = getSchema(okapiHeaders);
    String query = "SELECT * FROM pg_catalog.pg_class c JOIN pg_catalog.pg_index i ON (c.oid = i.indexrelid ) " + "JOIN pg_class t ON (i.indrelid = t.oid ) JOIN pg_namespace n ON (c.relnamespace = n.oid ) " + "WHERE c.relkind = 'i' AND n.nspname = '" + schema + "';";
    try {
        PostgresClient.getInstance(vertxContext.owner()).select(query, reply -> {
            if (reply.succeeded()) {
                int[] indexes2delete = new int[] { 0 };
                RowSet<Row> rs = reply.result();
                StringBuilder concatIndexNames = new StringBuilder();
                RowIterator<Row> iterator = rs.iterator();
                while (iterator.hasNext()) {
                    Row row = iterator.next();
                    String indexName = row.getString(0);
                    if (!indexName.endsWith("_pkey")) {
                        indexes2delete[0]++;
                        if (concatIndexNames.length() > 0) {
                            concatIndexNames.append(", ");
                        }
                        concatIndexNames.append(schema).append(".").append(indexName);
                    }
                }
                String dropIndexQuery = "DROP INDEX " + concatIndexNames.toString() + ";";
                if (indexes2delete[0] > 0) {
                    PostgresClient.getInstance(vertxContext.owner()).select(dropIndexQuery, reply2 -> {
                        if (reply2.succeeded()) {
                            log.info("Deleted " + indexes2delete[0] + " indexes");
                            asyncResultHandler.handle(io.vertx.core.Future.succeededFuture(PutAdminPostgresDropIndexesResponse.respond204()));
                        } else {
                            log.error(reply.cause().getMessage(), reply.cause());
                            asyncResultHandler.handle(io.vertx.core.Future.failedFuture(reply2.cause().getMessage()));
                        }
                    });
                } else {
                    log.info("No indexes to delete");
                    asyncResultHandler.handle(io.vertx.core.Future.succeededFuture(PutAdminPostgresDropIndexesResponse.respond400WithTextPlain("No indexes to delete, for tenant " + TenantTool.tenantId(okapiHeaders))));
                }
            } else {
                log.error(reply.cause().getMessage(), reply.cause());
                asyncResultHandler.handle(io.vertx.core.Future.failedFuture(reply.cause().getMessage()));
            }
        });
    } catch (Exception e) {
        log.error(e.getMessage(), e);
        asyncResultHandler.handle(io.vertx.core.Future.failedFuture(e.getMessage()));
    }
}
Also used : Row(io.vertx.sqlclient.Row) Validate(org.folio.rest.annotations.Validate)

Example 20 with Row

use of io.vertx.sqlclient.Row in project raml-module-builder by folio-org.

the class PostgresClient method doStreamRowResults.

/**
 * @param transaction the transaction to close, null if not to close
 */
<T> void doStreamRowResults(RowStream<Row> rowStream, Class<T> clazz, Transaction transaction, QueryHelper queryHelper, PostgresClientStreamResult<T> streamResult, Handler<AsyncResult<PostgresClientStreamResult<T>>> replyHandler) {
    ResultInfo resultInfo = streamResult.resultInfo();
    Promise<PostgresClientStreamResult<T>> promise = Promise.promise();
    ResultsHelper<T> resultsHelper = new ResultsHelper<>(clazz);
    boolean isAuditFlavored = isAuditFlavored(resultsHelper.clazz);
    Map<String, Method> externalColumnSetters = new HashMap<>();
    AtomicInteger resultCount = new AtomicInteger();
    rowStream.handler(r -> {
        try {
            // for first row, get column names
            if (resultsHelper.offset == 0) {
                List<String> columnNames = getColumnNames(r);
                collectExternalColumnSetters(columnNames, resultsHelper.clazz, isAuditFlavored, externalColumnSetters);
            }
            @SuppressWarnings("unchecked") T objRow = (T) deserializeRow(resultsHelper, externalColumnSetters, isAuditFlavored, r);
            if (!resultsHelper.facet) {
                resultCount.incrementAndGet();
                if (!promise.future().isComplete()) {
                    // end of facets (if any) .. produce result
                    resultsHelper.facets.forEach((k, v) -> resultInfo.getFacets().add(v));
                    promise.complete(streamResult);
                    replyHandler.handle(promise.future());
                }
                streamResult.fireHandler(objRow);
            }
            resultsHelper.offset++;
        } catch (Exception e) {
            streamResult.handler(null);
            log.error(e.getMessage(), e);
            if (!promise.future().isComplete()) {
                promise.complete(streamResult);
                replyHandler.handle(promise.future());
            }
            rowStream.close();
            closeIfNonNull(transaction).onComplete((AsyncResult<Void> voidRes) -> streamResult.fireExceptionHandler(e));
        }
    }).endHandler(v2 -> {
        rowStream.close();
        closeIfNonNull(transaction).onComplete(ignore -> {
            resultInfo.setTotalRecords(getTotalRecords(resultCount.get(), resultInfo.getTotalRecords(), queryHelper.offset, queryHelper.limit));
            try {
                if (!promise.future().isComplete()) {
                    promise.complete(streamResult);
                    replyHandler.handle(promise.future());
                }
                streamResult.fireEndHandler();
            } catch (Exception ex) {
                streamResult.fireExceptionHandler(ex);
            }
        });
    }).exceptionHandler(e -> {
        rowStream.close();
        closeIfNonNull(transaction).onComplete(ignore -> {
            if (!promise.future().isComplete()) {
                promise.complete(streamResult);
                replyHandler.handle(promise.future());
            }
            streamResult.fireExceptionHandler(e);
        });
    });
}
Also used : RowStream(io.vertx.sqlclient.RowStream) Arrays(java.util.Arrays) AES(org.folio.rest.security.AES) Tuple(io.vertx.sqlclient.Tuple) UpdateSection(org.folio.rest.persist.Criteria.UpdateSection) MetadataUtil(org.folio.rest.tools.utils.MetadataUtil) OpenSSLEngineOptions(io.vertx.core.net.OpenSSLEngineOptions) RowIterator(io.vertx.sqlclient.RowIterator) Matcher(java.util.regex.Matcher) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ObjectMapperTool(org.folio.dbschema.ObjectMapperTool) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) Transaction(io.vertx.sqlclient.Transaction) Method(java.lang.reflect.Method) JdkSSLEngineOptions(io.vertx.core.net.JdkSSLEngineOptions) FacetManager(org.folio.rest.persist.facets.FacetManager) UUID(java.util.UUID) Future(io.vertx.core.Future) PoolOptions(io.vertx.sqlclient.PoolOptions) InvocationTargetException(java.lang.reflect.InvocationTargetException) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Criterion(org.folio.rest.persist.Criteria.Criterion) Results(org.folio.rest.persist.interfaces.Results) Buffer(io.vertx.core.buffer.Buffer) Pattern(java.util.regex.Pattern) SecretKey(javax.crypto.SecretKey) CQLWrapper(org.folio.rest.persist.cql.CQLWrapper) FacetField(org.folio.rest.persist.facets.FacetField) TemplateException(freemarker.template.TemplateException) HashMap(java.util.HashMap) ResultInfo(org.folio.rest.jaxrs.model.ResultInfo) Function(java.util.function.Function) PreparedStatement(io.vertx.sqlclient.PreparedStatement) ArrayList(java.util.ArrayList) SqlConnection(io.vertx.sqlclient.SqlConnection) RowSet(io.vertx.sqlclient.RowSet) AsyncResult(io.vertx.core.AsyncResult) PemTrustOptions(io.vertx.core.net.PemTrustOptions) LinkedList(java.util.LinkedList) PostgresTester(org.folio.util.PostgresTester) OpenSsl(io.netty.handler.ssl.OpenSsl) Iterator(java.util.Iterator) Envs(org.folio.rest.tools.utils.Envs) Promise(io.vertx.core.Promise) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Vertx(io.vertx.core.Vertx) PgPool(io.vertx.pgclient.PgPool) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) HashedMap(org.apache.commons.collections4.map.HashedMap) MultiKeyMap(org.apache.commons.collections4.map.MultiKeyMap) TimeUnit(java.util.concurrent.TimeUnit) JsonArray(io.vertx.core.json.JsonArray) PgConnection(io.vertx.pgclient.PgConnection) Row(io.vertx.sqlclient.Row) PgConnectOptions(io.vertx.pgclient.PgConnectOptions) Option(java.lang.StackWalker.Option) Handler(io.vertx.core.Handler) Collections(java.util.Collections) LogManager(org.apache.logging.log4j.LogManager) SslMode(io.vertx.pgclient.SslMode) HashMap(java.util.HashMap) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) TemplateException(freemarker.template.TemplateException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ResultInfo(org.folio.rest.jaxrs.model.ResultInfo)

Aggregations

Row (io.vertx.sqlclient.Row)22 PgPool (io.vertx.pgclient.PgPool)12 ArrayList (java.util.ArrayList)11 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)10 IOException (java.io.IOException)10 PgConnection (io.vertx.pgclient.PgConnection)9 RowSet (io.vertx.sqlclient.RowSet)9 SqlConnection (io.vertx.sqlclient.SqlConnection)9 Transaction (io.vertx.sqlclient.Transaction)9 LinkedList (java.util.LinkedList)9 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)9 Handler (io.vertx.core.Handler)8 RowImpl (io.vertx.pgclient.impl.RowImpl)8 PreparedStatement (io.vertx.sqlclient.PreparedStatement)8 Tuple (io.vertx.sqlclient.Tuple)8 RowDesc (io.vertx.sqlclient.impl.RowDesc)8 LocalRowSet (org.folio.rest.persist.helpers.LocalRowSet)8 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)7 AsyncResult (io.vertx.core.AsyncResult)7 Future (io.vertx.core.Future)7