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

io.github.pustike.persist.sql.SqlQuery Maven / Gradle / Ivy

/*
 * Copyright (C) 2016-2019 the original author or authors.
 *
 * 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 io.github.pustike.persist.sql;

import java.sql.Connection;
import java.util.List;
import java.util.Objects;

import io.github.pustike.persist.metadata.Schema;

/**
 * The query object, created by the repository, which can be used to insert, update, delete, select, find data.
 */
public final class SqlQuery {
    private final Connection connection;
    private final Schema schema;
    private int counter = 0;

    SqlQuery(Connection connection, Schema schema) {
        this.connection = connection;
        this.schema = schema;
    }

    Connection getConnection() {
        return connection;
    }

    Schema getSchema() {
        return schema;
    }

    void incrementCounter() {
        counter++;
    }

    int decrementCounter() {
        return --counter;
    }

    void beginTransaction() {
        try {
            connection.setAutoCommit(false);// begin transaction
        } catch (Exception ex) {
            throw new RuntimeException("Couldn't begin transaction", ex);
        }
    }

    void close(boolean onSuccess) {
        try {
            if (onSuccess) {// commit changes
                connection.commit();
            } else { // rollback uncommitted changes
                connection.rollback();
            }
        } catch (Exception ex) {
            try {// ensure rollback is called if commit fails!
                connection.rollback();
            } catch (Exception ignored) {
            }
            throw new RuntimeException("Couldn't commit transaction", ex);
        } finally {
            try {// close connection
                connection.close();
            } catch (Exception ignored) {
            }
        }
    }

    /**
     * Execute a statement to insert the given entity data.
     * @param entity a new entity instance to be inserted
     */
    public void insert(Object entity) {
        Objects.requireNonNull(entity);
        EntitySql.insert(this, entity.getClass()).execute(entity);
    }

    /**
     * Execute a statement to insert the given list of entities in a batch size of 100.
     * @param entityList a list of new entities to be inserted
     * @param  type of the entity
     */
    public  void batchInsert(List entityList) {
        if (entityList.isEmpty()) {
            return;
        }
        Class entityClass = entityList.get(0).getClass();
        EntitySql.insert(this, entityClass).executeInBatch(entityList);
    }

    /**
     * Execute a statement to insert the given list of entities in batch of 100 and on conflict update the data.
     * @param entityList a list of entities to be inserted or updated
     * @param onConflict columns defining the conflict constraint
     * @param updateClause the update clause for the excluded data as a native query
     * @param  type of the entity
     */
    public  void batchUpsert(List entityList, String onConflict, String updateClause) {
        if (entityList.isEmpty()) {
            return;
        }
        Class entityClass = entityList.get(0).getClass();
        EntitySql.insert(this, entityClass, onConflict, updateClause).executeInBatch(entityList);
    }

    /**
     * Execute a statement to update specified fields on the given entity data.
     * @param entity an existing entity instance to be updated
     * @param fieldGroup the name of the field group
     */
    public void update(Object entity, String fieldGroup) {
        Objects.requireNonNull(entity);
        EntitySql entitySql = EntitySql.update(this, entity.getClass(), fieldGroup);
        if (entitySql != null) {
            entitySql.execute(entity);
        }
    }

    /**
     * Execute a statement to update specified fields on the given list of entities.
     * @param entityList a list of existing entities to be updated
     * @param fieldGroup the name of the field group
     * @param  type of the entity
     */
    public  void batchUpdate(List entityList, String fieldGroup) {
        if (entityList.isEmpty()) {
            return;
        }
        Class entityClass = entityList.get(0).getClass();
        EntitySql entitySql = EntitySql.update(this, entityClass, fieldGroup);
        if (entitySql != null) {
            entitySql.executeInBatch(entityList);
        }
    }

    /**
     * Insert or update the given entity.
     * @param entity the entity instance to be saved.
     * @param isNewEntity execute insert query if new entity, else update with the given field group
     * @param fieldGroup the name of the field group
     * @param  type of the entity
     * @return the same instance of the entity set with returned values, like id, version
     */
    public  E save(E entity, boolean isNewEntity, String fieldGroup) {
        if (isNewEntity) {
            insert(entity);
        } else {
            update(entity, fieldGroup);
        }
        return entity;
    }

    /**
     * Execute a statement to delete the given entity.
     * @param entity the entity to be deleted
     * @return the modified row count
     */
    public int delete(Object entity) {
        Objects.requireNonNull(entity);
        return EntitySql.delete(this, entity);
    }

    /**
     * Execute a statement to delete the given list of entities.
     * @param entityList the list of entities to be deleted
     * @param  type of the entity
     */
    public  void batchDelete(List entityList) {
        if (entityList.isEmpty()) {
            return;
        }
        EntitySql.batchDelete(this, entityList);
    }

    /**
     * Execute a select from entity table, on the given primary key, for update.
     * @param entityClass the entity class
     * @param primaryKey the primary key value to select
     * @param  type of the entity
     */
    public  void lockForUpdate(Class entityClass, Object primaryKey) {
        EntitySql.lockForUpdate(this, entityClass, primaryKey);
    }

    /**
     * Execute a select from entity table, on the given primary key and return the entity instance with all values set.
     * @param entityClass the entity class
     * @param primaryKey the primary key value to select
     * @param  type of the entity
     * @return an entity instance with all selected values set
     */
    public  E select(Class entityClass, Object primaryKey) {
        return select(entityClass, primaryKey, null);
    }

    /**
     * Execute a select columns from fieldGroup, from entity table, on the given primary key
     * and return the entity instance with all values set.
     * @param entityClass the entity class
     * @param primaryKey the primary key value to select
     * @param fieldGroup name of the field group
     * @param  type of the entity
     * @return an entity instance with all selected values set
     */
    public  E select(Class entityClass, Object primaryKey, String fieldGroup) {
        return new SelectQuery(this, entityClass, fieldGroup, primaryKey).find(false);
    }

    /**
     * Execute a select from entity table, on the given primary key, for update
     * and return the entity instance with all values set.
     * @param entityClass the entity class
     * @param primaryKey the primary key value to select
     * @param  type of the entity
     * @return an entity instance with all selected values set
     */
    public  E selectForUpdate(Class entityClass, Object primaryKey) {
        return selectForUpdate(entityClass, primaryKey, null);
    }

    /**
     * Execute a select columns from fieldGroup, from entity table, on the given primary key, for update
     * and return the entity instance with all values set.
     * @param entityClass the entity class
     * @param primaryKey the primary key value to select
     * @param fieldGroup name of the field group
     * @param  type of the entity
     * @return an entity instance with all selected values set
     */
    public  E selectForUpdate(Class entityClass, Object primaryKey, String fieldGroup) {
        return new SelectQuery(this, entityClass, fieldGroup, primaryKey).find(true);
    }

    /**
     * Create a new {@link Finder} instance for the given entity class.
     * @param entityClass the entity class
     * @param  type of the entity
     * @return the finder api for the given entity
     */
    public  Finder find(Class entityClass) {
        return find(entityClass, "x");
    }

    /**
     * Create a new {@link Finder} instance for the given entity class using the sql alias.
     * @param entityClass the entity class
     * @param alias the sql alias to be used for the entity table
     * @param  type of the entity
     * @return the finder api for the given entity
     */
    public  Finder find(Class entityClass, String alias) {
        return new Finder<>(this, entityClass, alias);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy