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