io.github.josecarlosbran.JBSqlUtils.DataBase.Methods_Conexion Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jbsqlutils Show documentation
Show all versions of jbsqlutils Show documentation
JBSqlUtils es un ORM desarrollado en java por José Carlos Alfredo Bran Aguirre,
que permite gestionar BD's SQLite, MySQL, MariaDB, PostgreSQL y SQLServer, de una manera fácil
y rápida sin interrumpir la ejecución del hilo principal del programa, lo cual la hace un potente ORM,
por medio del cual tendrá acceso a un CRUD, configurando únicamente la conexión del
modelo, los atributos que posee la tabla en BD's cómo variables que pertenecerán al modelo en su aplicación.
JBSqlUtils también proporciona un potente generador de instrucciones SQL que le permitirá crear
o eliminar una tabla, insertar, seleccionar, actualizar o eliminar registros de una tabla
en su BD's sin necesidad de instanciar un modelo cómo tal, únicamente tendrá que configurar previamente
la conexión a su BD's.
Lo cual la hace un potente ORM para aplicaciones android y sistemas empresariales que tengan
la necesidad de poder conectarse a alguna de estas 4 tipos de BD's, cabe mencionar que para ello utiliza
el SQLite JDBC de org.xerial, org.postgresql, mysql y com.microsoft.sqlserver.
Para mayor información, consultar el enlace del proyecto
The newest version!
/***
* Copyright (C) 2022 El proyecto de código abierto JBSqlUtils de José Bran
*
* Con licencia de Apache License, Versión 2.0 (la "Licencia");
* no puede usar este archivo excepto de conformidad con la Licencia.
* Puede obtener una copia de la Licencia en
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* A menos que lo exija la ley aplicable o se acuerde por escrito, el software
* distribuido bajo la Licencia se distribuye "TAL CUAL",
* SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ya sean expresas o implícitas.
* Consulte la Licencia para conocer el idioma específico que rige los permisos y
* limitaciones bajo la Licencia.
*/
package io.github.josecarlosbran.JBSqlUtils.DataBase;
import com.josebran.LogsJB.LogsJB;
import io.github.josecarlosbran.JBSqlUtils.Anotations.Actions;
import io.github.josecarlosbran.JBSqlUtils.Anotations.ColumnDefined;
import io.github.josecarlosbran.JBSqlUtils.Anotations.ForeignKey;
import io.github.josecarlosbran.JBSqlUtils.Anotations.Index;
import io.github.josecarlosbran.JBSqlUtils.Enumerations.Constraint;
import io.github.josecarlosbran.JBSqlUtils.Enumerations.DataBase;
import io.github.josecarlosbran.JBSqlUtils.Enumerations.DataType;
import io.github.josecarlosbran.JBSqlUtils.Exceptions.ConexionUndefind;
import io.github.josecarlosbran.JBSqlUtils.Exceptions.DataBaseUndefind;
import io.github.josecarlosbran.JBSqlUtils.Exceptions.PropertiesDBUndefined;
import io.github.josecarlosbran.JBSqlUtils.Utilities.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.json.JSONObject;
import java.io.File;
import java.lang.reflect.*;
import java.sql.Date;
import java.sql.*;
import java.util.Set;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static io.github.josecarlosbran.JBSqlUtils.Utilities.UtilitiesJB.*;
/**
* @author Jose Bran
* Clase que proporciona los métodos de conexión necesarios para que el modelo pueda realizar
* la conversion de datos entre java y sql, así mismo proporciona métodos de logica del manejor del resultado
* como de envíar valores a BD's
*/
class Methods_Conexion extends Conexion {
/**
* Constructor de la clase Conexión que se encarga de inicializar las propiedades de conexión del modelo,
* las cuales las obtiene de las propiedades del sistema Java.
*/
protected Methods_Conexion() {
super();
this.getMethodsModel();
this.getFieldsModel();
}
/**
* Constructor de la clase Conexión que se encarga de inicializar las propiedades de conexión del modelo,
* las cuales las obtiene de las propiedades del sistema Java.
*
* @param getPropertySystem Indica si el modelo obtendra las propiedades de conexión de las propiedades del sistema
*/
protected Methods_Conexion(Boolean getPropertySystem) {
super(getPropertySystem);
this.getMethodsModel();
this.getFieldsModel();
}
/**
* Obtiene la lista de métodos pertenecientes al modelo que lo invoca.
*
* @param Definición del procedimiento que indica que cualquier clase podra invocar el metodo.
*/
protected synchronized void getMethodsModel() {
Method[] metodos = this.getClass().getMethods();
String classColumn = Column.class.getSimpleName();
List getMethods = this.getMethodsGetOfModel();
List setMethods = this.getMethodsSetOfModel();
for (Method metodo : metodos) {
String returnType = metodo.getReturnType().getSimpleName();
String nameMetodo = metodo.getName();
Parameter[] parametros = metodo.getParameters();
if (returnType.equalsIgnoreCase(classColumn) && StringUtils.startsWithIgnoreCase(nameMetodo, "get")) {
getMethods.add(metodo);
} else if (parametros.length == 1 && parametros[0].getType().getSimpleName().equalsIgnoreCase(classColumn)
&& StringUtils.startsWithIgnoreCase(nameMetodo, "set")) {
setMethods.add(metodo);
}
}
}
/**
* este metodo esta creado para ver si la clase actual es una subclase de JBSqlUtils,
* mediante los get se obtienen todos los campos de la clase actual y algunos que tienen datos especificos,
* los añade a una coleccion existente, pero los filtra primero.
*
* @param es un metodo generico, se puede trabajar con diferentes tipos especificados en la instancia.
*/
protected synchronized void getFieldsModel() {
//se esta obteniendo el nombre simple de la clase JBSqlUtils y se esta almacenando en la variable declarada
String JBSQLUTILSNAME = JBSqlUtils.class.getSimpleName();
//se obtiene el nombre de la superclase y se almacena en superclasemodelo
String SuperClaseModelo = this.getClass().getSuperclass().getSimpleName();
if (StringUtils.equalsIgnoreCase(JBSQLUTILSNAME, SuperClaseModelo)) {
//Obtiene los Fields del modelo
List modelFields = Arrays.asList(this.getClass().getDeclaredFields());
List modelFieldsWithAnotations =
Arrays.asList(FieldUtils.getFieldsWithAnnotation(this.getClass(),
ColumnDefined.class));
// Combina y filtra los campos
List combinedFields = Stream.concat(
modelFields.stream().filter(field -> !modelFieldsWithAnotations.contains(field)),
modelFieldsWithAnotations.stream()
).collect(Collectors.toList());
this.getFieldsOfModel().addAll(modelFields);
}
}
/**
* Obtiene la conexión del modelo a la BD's con las propiedades definidas.
*
* @return Retorna la conexión del modelo a la BD's con las propiedades definidas.
*/
public synchronized Connection getConnection() {
Connection connect = null;
try {
if (this.getContadorConexiones() == 0) {
}
String url;
String usuario = this.getUser();
String password = this.getPassword();
if (this.getDataBaseType() == DataBase.PostgreSQL) {
String host = this.getHost();
Class.forName("org.postgresql.Driver");
DriverManager.registerDriver(new org.postgresql.Driver());
if (!stringIsNullOrEmpty(this.getPort())) {
host = host + ":" + this.getPort();
}
url = "jdbc:" + this.getDataBaseType().getDBType() + "://" +
host;
if (!stringIsNullOrEmpty(this.getBD())) {
url = url + "/" + this.getBD();
}
if (!stringIsNullOrEmpty(this.getPropertisURL())) {
url = url + this.getPropertisURL();
}
LogsJB.debug("Url de conexion a DB: " + url);
connect = DriverManager.getConnection(url, usuario, password);
}
if (this.getDataBaseType() == DataBase.MySQL) {
connect = null;
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
url = "jdbc:" + this.getDataBaseType().getDBType() + "://" +
this.getHost() + ":" + this.getPort() + "/" + this.getBD();
if (!stringIsNullOrEmpty(this.getPropertisURL())) {
url = url + this.getPropertisURL();
}
LogsJB.debug("Url de conexion a DB: " + url);
connect = DriverManager.getConnection(url, usuario, password);
}
if (this.getDataBaseType() == DataBase.MariaDB) {
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
connect = null;
url = "jdbc:" + this.getDataBaseType().getDBType() + "://" +
this.getHost() + ":" + this.getPort() + "/" + this.getBD();
if (!stringIsNullOrEmpty(this.getPropertisURL())) {
url = url + this.getPropertisURL();
}
LogsJB.debug("Url de conexion a DB: " + url);
connect = DriverManager.getConnection(url, usuario, password);
}
if (this.getDataBaseType() == DataBase.SQLServer) {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());
connect = null;
String host = this.getHost();
if (!stringIsNullOrEmpty(this.getPort())) {
host = host + ":" + this.getPort();
}
url = "jdbc:" + this.getDataBaseType().getDBType() + "://" +
host;
if (!stringIsNullOrEmpty(this.getBD())) {
url = url + ";databaseName=" + this.getBD();
}
if (!stringIsNullOrEmpty(this.getPropertisURL())) {
url = url + this.getPropertisURL();
}
LogsJB.debug("Url de conexion a DB: " + url);
connect = DriverManager.getConnection(url, usuario, password);
}
if (this.getDataBaseType() == DataBase.SQLite) {
Class.forName("org.sqlite.JDBC").newInstance();
DriverManager.registerDriver(new org.sqlite.JDBC());
//Rutas de archivos
File fichero = new File(this.getBD());
//Verifica si existe la carpeta Logs, si no existe, la Crea
String carpeta = fichero.getParent();
if (!Objects.isNull(carpeta) && !(new File(carpeta).exists())) {
File directorio = new File(carpeta);
directorio.mkdirs();
LogsJB.debug("Crea el directorio donde estara la BD's SQLite: " + fichero.getParent());
}
url = "jdbc:" + this.getDataBaseType().getDBType() + ":" + this.getBD();
LogsJB.debug("Url de conexion a DB: " + url);
connect = DriverManager.getConnection(url);
}
LogsJB.info("Conexión a BD's " + this.getBD() + " Realizada exitosamente " + this.getClass().getSimpleName());
} catch (Exception e) {
LogsJB.fatal("Excepción disparada al obtener la conexión a la BD's proporcionada, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
}
this.setContadorConexiones(this.getContadorConexiones() + 1);
return connect;
}
/**
* Cierra la conexión a BD's
*
* @param connect Conexión que se desea cerrar
*/
public void closeConnection(Connection connect) {
try {
if (Objects.isNull(connect)) {
//Si la propiedad del sistema no esta definida, Lanza una Exepción
throw new ConexionUndefind("No se a conectado el modelo a la BD's");
}
if (!connect.isClosed()) {
connect.close();
LogsJB.info("Conexión a BD's cerrada " + this.getClass().getSimpleName());
}
} catch (ConexionUndefind | SQLException e) {
LogsJB.warning("El modelo no estaba conectado a la BD's por lo cual no se cerrara la conexión: " + ExceptionUtils.getStackTrace(e));
}
}
/**
* Verifica la existencia de la tabla correspondiente al modelo en BD's
*
* @return True si la tabla correspondiente al modelo existe en BD's, de lo contrario False.
*/
public CompletableFuture tableExist() {
return CompletableFuture.supplyAsync(() -> {
Connection connect = null;
ResultSet tables = null;
try {
LogsJB.info("Comienza a verificar la existencia de la tabla");
connect = this.getConnection();
DatabaseMetaData metaData = connect.getMetaData();
String databaseName = this.getBD();
tables = metaData.getTables(null, null, "%", null);
LogsJB.trace("Revisara el resultSet");
while (tables.next()) {
TablesSQL temp = new TablesSQL();
temp.setTABLE_CAT(tables.getString(1));
temp.setTABLE_SCHEM(tables.getString(2));
temp.setTABLE_NAME(tables.getString(3));
temp.setTABLE_TYPE(tables.getString(4));
temp.setREMARKS(tables.getString(5));
if (this.getDataBaseType() != DataBase.SQLServer) {
temp.setTYPE_CAT(tables.getString(6));
temp.setTYPE_SCHEM(tables.getString(7));
temp.setTYPE_NAME(tables.getString(8));
temp.setSELF_REFERENCING_COL_NAME(tables.getString(9));
temp.setREF_GENERATION(tables.getString(10));
}
String nameModel = this.getTableName();
String nameTable = temp.getTABLE_NAME();
String databaseTemp = tables.getString(1);
String databaseTemp2 = tables.getString(2);
boolean tablaisofDB = true;
if (nameModel.equalsIgnoreCase(nameTable)) {
LogsJB.debug("Base de datos del modelo: " + databaseName + " Base de datos del servidor: " + databaseTemp);
}
if (!stringIsNullOrEmpty(databaseTemp) && !databaseName.equalsIgnoreCase(databaseTemp)) {
tablaisofDB = false;
}
if (!tablaisofDB && !stringIsNullOrEmpty(databaseTemp2)) {
tablaisofDB = databaseName.equalsIgnoreCase(databaseTemp2);
}
if (this.getDataBaseType() == DataBase.PostgreSQL && nameModel.equalsIgnoreCase(nameTable)) {
tablaisofDB = true;
}
if (nameModel.equalsIgnoreCase(nameTable) && tablaisofDB) {
LogsJB.debug("Base de datos del modelo: " + databaseName + " Base de datos del servidor3: " + databaseTemp);
this.setTableExist(Boolean.TRUE);
this.setTableName(nameTable);
this.setTabla(temp);
ResultSet clavePrimaria = metaData.getPrimaryKeys(temp.getTABLE_CAT(), temp.getTABLE_SCHEM(), nameTable);
if (clavePrimaria.next()) {
PrimaryKey clave = new PrimaryKey();
clave.setTABLE_CAT(clavePrimaria.getString(1));
clave.setTABLE_SCHEM(clavePrimaria.getString(2));
clave.setTABLE_NAME(clavePrimaria.getString(3));
clave.setCOLUMN_NAME(clavePrimaria.getString(4));
clave.setKEY_SEQ(clavePrimaria.getShort(5));
clave.setPK_NAME(clavePrimaria.getString(6));
this.getTabla().setClaveprimaria(clave);
}
LogsJB.info("La tabla correspondiente a este modelo, existe en BD's " + this.getClass().getSimpleName());
getColumnsTable(connect);
return true;
}
}
LogsJB.trace("Termino de Revisarar el resultSet");
if (!this.getTableExist()) {
LogsJB.info("La tabla correspondiente a este modelo, No existe en BD's " + this.getClass().getSimpleName());
return false;
}
} catch (Exception e) {
LogsJB.fatal("Excepción disparada en el método que verifica si existe la tabla correspondiente al modelo, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
return false;
} finally {
if (tables != null) {
try {
tables.close();
} catch (SQLException e) {
LogsJB.warning("Error closing ResultSet: " + ExceptionUtils.getStackTrace(e));
}
}
if (connect != null) {
this.closeConnection(connect);
}
}
return false;
});
}
/**
* Obtiene las columnas que tiene la tabla correspondiente al modelo en BD's.
*
* @param connect a BD's para obtener la metadata
* @throws SQLException Si sucede una excepción en la ejecución asincrona de la sentencia en BD's lanza esta excepción
*/
protected void getColumnsTable(Connection connect) throws SQLException {
LogsJB.debug("Comienza a obtener las columnas que le pertenecen a la tabla " + this.getTableName());
DatabaseMetaData metaData = null;
ResultSet columnas = null;
try {
LogsJB.trace("Obtuvo el objeto conexión");
metaData = connect.getMetaData();
LogsJB.trace("Ya tiene el MetaData de la BD's");
columnas = metaData.getColumns(this.getTabla().getTABLE_CAT(),
this.getTabla().getTABLE_SCHEM(), this.getTableName(), null);
LogsJB.debug("Ya tiene el resultset con las columnas de la tabla");
// Limpiar las listas antes de llenarlas
this.getTabla().getColumnas().clear();
this.getTabla().getColumnsExist().clear();
while (columnas.next()) {
ColumnsSQL temp = new ColumnsSQL();
temp.setTABLE_CAT(columnas.getString(1));
temp.setTABLE_SCHEM(columnas.getString(2));
temp.setTABLE_NAME(columnas.getString(3));
temp.setCOLUMN_NAME(columnas.getString(4));
this.getTabla().getColumnsExist().add(columnas.getString(4).toUpperCase());
temp.setDATA_TYPE(columnas.getInt(5));
temp.setTYPE_NAME(columnas.getString(6));
temp.setCOLUMN_SIZE(columnas.getInt(7));
temp.setDECIMAL_DIGITS(columnas.getInt(9));
temp.setNUM_PREC_RADIX(columnas.getInt(10));
temp.setNULLABLE(columnas.getInt(11));
temp.setREMARKS(columnas.getString(12));
temp.setCOLUMN_DEF(columnas.getString(13));
temp.setCHAR_OCTET_LENGTH(columnas.getInt(16));
temp.setORDINAL_POSITION(columnas.getInt(17));
temp.setIS_NULLABLE(columnas.getString(18));
temp.setSCOPE_CATALOG(columnas.getString(19));
temp.setSCOPE_SCHEMA(columnas.getString(20));
temp.setSCOPE_TABLE(columnas.getString(21));
temp.setSOURCE_DATA_TYPE(columnas.getShort(22));
temp.setIS_AUTOINCREMENT(columnas.getString(23));
temp.setIS_GENERATEDCOLUMN(columnas.getString(24));
this.getTabla().getColumnas().add(temp);
}
LogsJB.debug("Información de las columnas de la tabla correspondiente al modelo obtenida " + this.getClass().getSimpleName());
} catch (SQLException e) {
LogsJB.fatal("Excepción al obtener las columnas de la tabla: " + ExceptionUtils.getStackTrace(e));
throw e;
} finally {
if (columnas != null) {
try {
columnas.close();
} catch (SQLException e) {
LogsJB.warning("Error al cerrar ResultSet: " + ExceptionUtils.getStackTrace(e));
}
}
if (connect != null) {
this.closeConnection(connect);
}
}
this.getTabla().getColumnas().sort(Comparator.comparing(ColumnsSQL::getORDINAL_POSITION));
}
/**
* Metodo que actualiza la información que el modelo tiene sobre lo que existe en BD's'
* y Recarga el modelo si este existía previamente en BD's
*
* @throws Exception Lanza una Excepción si ocurre algun error al ejecutar el metodo refresh
*/
public void refresh() throws Exception {
this.reloadModel();
}
/**
* Refresca el modelo con la información de BD's, se perderan las modificaciones que se hayan realizadas sobre el modelo,
* si estas no han sido plasmadas en BD's.
*
* @param Definición del procedimiento que indica que cualquier clase podra invocar el método.
* @return True si el modelo fue recargado desde BD's, False caso contrario.
* @throws Exception Si sucede una excepción en la ejecución asyncrona de la sentencia en BD's
* captura la excepción y la lanza en el hilo principal
*/
public Boolean reloadModel() throws Exception {
this.setTaskIsReady(false);
Boolean reloadModel;
this.validarTableExist(this).join();
CompletableFuture> future = CompletableFuture.supplyAsync(() -> {
Boolean result = false;
Connection connect = null;
ResultSet registros = null;
try {
if (this.getTableExist() && this.getModelExist()) {
StringBuilder sql = new StringBuilder("SELECT * FROM ").append(this.getTableName()).append(" WHERE ");
String namePrimaryKey = this.getTabla().getClaveprimaria().getCOLUMN_NAME();
List columnas = this.getFieldsOfModel();
List values = new ArrayList<>();
for (Field columna : columnas) {
if ((StringUtils.equalsIgnoreCase(namePrimaryKey, this.getColumnName(columna)) && !this.getValueColumnIsNull(this, columna))
|| (this.getColumnIsIndexValidValue(this, columna))) {
values.add(columna);
if (values.size() > 1) {
sql.append(" AND ");
}
sql.append(this.getColumnName(columna)).append(" = ?");
}
}
sql.append(";");
LogsJB.info(sql.toString());
connect = this.getConnection();
PreparedStatement ejecutor = connect.prepareStatement(sql.toString());
int auxiliar = 0;
for (Field value : values) {
auxiliar++;
convertJavaToSQL(this, value, ejecutor, auxiliar);
}
registros = ejecutor.executeQuery();
if (registros.next()) {
procesarResultSetOneResult((T) this, registros);
result = true;
}
return new ResultAsync<>(result, null);
} else {
LogsJB.warning("Tabla correspondiente al modelo no existe en BD's por esa razón no se pudo recuperar el Registro: " + this.getTableName());
return new ResultAsync<>(result, null);
}
} catch (Exception e) {
LogsJB.fatal("Excepción disparada en el método que Recupera la lista de registros que cumplen con la sentencia SQL de la BD's, Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
return new ResultAsync<>(result, e);
} finally {
if (registros != null) {
try {
registros.close();
} catch (SQLException e) {
LogsJB.warning("Error al cerrar ResultSet: " + ExceptionUtils.getStackTrace(e));
}
}
if (connect != null) {
this.closeConnection(connect);
}
}
});
ResultAsync resultado = future.get();
this.setTaskIsReady(true);
if (!Objects.isNull(resultado.getException())) {
throw resultado.getException();
}
reloadModel = resultado.getResult();
return reloadModel;
}
/**
* Metodo que setea la información de la columna Java en el respectivo tipo de Dato SQL
*
* @param columnsSQL Columna java que será analizada
* @param ejecutor PreparedStatement sobre el cual se estara envíando la información de la columna
* @param auxiliar Indice que indica la posición del parametro en el ejecutor.
* @throws SQLException Lanza esta excepción si sucede algún problema al setear el valor Java en el ejecutor.
*/
protected void convertJavaToSQL(Column columnsSQL, PreparedStatement ejecutor, int auxiliar) throws SQLException {
LogsJB.debug("DataType de la columna: " + columnsSQL.getDataTypeSQL());
LogsJB.debug("Indice donde insertara la columna: " + auxiliar);
LogsJB.debug("Valor de la columna: " + columnsSQL.getValor());
if ((columnsSQL.getDataTypeSQL() == DataType.NCHAR) || (columnsSQL.getDataTypeSQL() == DataType.NVARCHAR)) {
//Caracteres y cadenas de Texto
ejecutor.setNString(auxiliar, (String) columnsSQL.getValor());
} else if ((columnsSQL.getDataTypeSQL() == DataType.CHAR) || (columnsSQL.getDataTypeSQL() == DataType.VARCHAR)
|| (columnsSQL.getDataTypeSQL() == DataType.LONGVARCHAR)
|| (columnsSQL.getDataTypeSQL() == DataType.TEXT)
) {
//Caracteres y cadenas de Texto
ejecutor.setString(auxiliar, (String) columnsSQL.getValor());
} else if ((columnsSQL.getDataTypeSQL() == DataType.SMALLINT) || (columnsSQL.getDataTypeSQL() == DataType.TINYINT)
|| (columnsSQL.getDataTypeSQL() == DataType.INTEGER) || (columnsSQL.getDataTypeSQL() == DataType.IDENTITY)
|| (columnsSQL.getDataTypeSQL() == DataType.SERIAL)) {
//Valores Enteros
Number valor = (Number) columnsSQL.getValor();
ejecutor.setInt(auxiliar, valor.intValue());
} else if ((columnsSQL.getDataTypeSQL() == DataType.NUMERIC) || (columnsSQL.getDataTypeSQL() == DataType.DECIMAL)
|| (columnsSQL.getDataTypeSQL() == DataType.MONEY) || (columnsSQL.getDataTypeSQL() == DataType.SMALLMONEY)
|| (columnsSQL.getDataTypeSQL() == DataType.DOUBLE)) {
//Dinero y numericos que tienen decimales
Number valor = (Number) columnsSQL.getValor();
ejecutor.setDouble(auxiliar, valor.doubleValue());
} else if ((columnsSQL.getDataTypeSQL() == DataType.BIT)
|| (columnsSQL.getDataTypeSQL() == DataType.BOOLEAN)
|| (columnsSQL.getDataTypeSQL() == DataType.BOOL)) {
//Valores Booleanos
ejecutor.setBoolean(auxiliar, (Boolean) columnsSQL.getValor());
} else if ((columnsSQL.getDataTypeSQL() == DataType.REAL) || (columnsSQL.getDataTypeSQL() == DataType.FLOAT)) {
//Valores Flotantes
Number valor = (Number) columnsSQL.getValor();
ejecutor.setFloat(auxiliar, valor.floatValue());
} else if ((columnsSQL.getDataTypeSQL
() == DataType.BINARY) || (columnsSQL.getDataTypeSQL() == DataType.VARBINARY)
|| (columnsSQL.getDataTypeSQL() == DataType.LONGVARBINARY)) {
//Valores binarios
ejecutor.setBytes(auxiliar, (byte[]) columnsSQL.getValor());
} else if ((columnsSQL.getDataTypeSQL() == DataType.DATE)) {
//DATE
ejecutor.setDate(auxiliar, (Date) columnsSQL.getValor());
} else if ((columnsSQL.getDataTypeSQL() == DataType.TIME)) {
//Time
ejecutor.setTime(auxiliar, (Time) columnsSQL.getValor());
} else if ((columnsSQL.getDataTypeSQL() == DataType.TIMESTAMP) || (columnsSQL.getDataTypeSQL() == DataType.DATETIME)
|| (columnsSQL.getDataTypeSQL() == DataType.SMALLDATETIME)
|| (columnsSQL.getDataTypeSQL() == DataType.DATETIME2)) {
//TimeStamp
ejecutor.setTimestamp(auxiliar, (Timestamp) columnsSQL.getValor());
} else {
LogsJB.debug("No logro setear el tipo de dato");
ejecutor.setObject(auxiliar, columnsSQL.getValor());
}
}
/**
* Metodo que setea la información de la columna Java en el respectivo tipo de Dato SQL
*
* @param columnsSQL Columna java que será analizada
* @param ejecutor PreparedStatement sobre el cual se estara envíando la información de la columna
* @param auxiliar Indice que indica la posición del parametro en el ejecutor.
* @throws SQLException Lanza esta excepción si sucede algún problema al setear el valor Java en el ejecutor.
* @throws IllegalAccessException Lanza esta excepción si sucede algún problema al setear el valor Java en el ejecutor.
*/
protected void convertJavaToSQL(Object modelo, Field columnsSQL, PreparedStatement ejecutor, int auxiliar) throws SQLException, IllegalAccessException {
LogsJB.debug("DataType de la columna: " + columnsSQL.getType());
LogsJB.debug("Indice donde insertara la columna: " + auxiliar);
Object valor = getValueColumn(modelo, columnsSQL);
LogsJB.debug("Valor de la columna: " + valor);
Class> columnType = columnsSQL.getType();
if (columnType.isAssignableFrom(String.class)) {
//Caracteres y cadenas de Texto
ejecutor.setString(auxiliar, (String) valor);
} else if (columnType.isAssignableFrom(Double.class)) {
Number value = (Number) valor;
ejecutor.setDouble(auxiliar, value.doubleValue());
} else if (columnType.isAssignableFrom(Integer.class)) {
Number value = (Number) valor;
ejecutor.setInt(auxiliar, value.intValue());
} else if (columnType.isAssignableFrom(Float.class)) {
Number value = (Number) valor;
ejecutor.setFloat(auxiliar, value.floatValue());
} else if (columnType.isAssignableFrom(Boolean.class)) {
Boolean value = (Boolean) valor;
ejecutor.setBoolean(auxiliar, value.booleanValue());
} else if (columnType.isAssignableFrom(byte[].class)) {
//Valores binarios
ejecutor.setBytes(auxiliar, (byte[]) valor);
} else if (columnType.isAssignableFrom(Date.class)) {
//DATE
ejecutor.setDate(auxiliar, (Date) valor);
} else if (columnType.isAssignableFrom(Time.class)) {
//Time
ejecutor.setTime(auxiliar, (Time) valor);
} else if (columnType.isAssignableFrom(Timestamp.class)) {
//Timestamp
ejecutor.setTimestamp(auxiliar, (Timestamp) valor);
} else {
ejecutor.setObject(auxiliar, valor);
}
}
/**
* Metodo que convierte la información obtenida de BD's a Java
*
* @param columna Columna del modelo
* @param resultado ResulSet que está siendo evaludo
* @param field Columna SQL que corresponde a la columna del modelo
* @param invocador Invocador del metodo
* @throws SQLException Lanza esta excepción de suceder algún problema con el ResultSet
* @throws InvocationTargetException Lanza esta excepción si hubiera algún problema al invocar el metodo Set
* @throws IllegalAccessException Lanza esta excepción si hubiera algún problema al invocar el metodo Set
*/
protected void convertSQLtoJava(ColumnsSQL columna, ResultSet resultado, Field field, Object invocador) throws SQLException, InvocationTargetException, IllegalAccessException {
Class> fieldType = field.getType();
String columnName = columna.getCOLUMN_NAME();
if (fieldType.isAssignableFrom(String.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getString(columnName), true);
} else if (fieldType.isAssignableFrom(Double.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getDouble(columnName), true);
} else if (fieldType.isAssignableFrom(Integer.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getInt(columnName), true);
} else if (fieldType.isAssignableFrom(Float.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getFloat(columnName), true);
} else if (fieldType.isAssignableFrom(Boolean.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getBoolean(columnName), true);
} else if (fieldType.isAssignableFrom(byte[].class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getBytes(columnName), true);
} else if (fieldType.isAssignableFrom(Date.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getDate(columnName), true);
} else if (fieldType.isAssignableFrom(Time.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getTime(columnName), true);
} else if (fieldType.isAssignableFrom(Timestamp.class)) {
FieldUtils.writeField(invocador, field.getName(), resultado.getTimestamp(columnName), true);
} else {
FieldUtils.writeField(invocador, field.getName(), resultado.getObject(columnName), true);
}
}
/**
* Agrega la columna como una propiedad del Json Object envíado como parametro
*
* @param columna Columna que se obtendra.
* @param resultado ResultSet del cual se obtendra el valor para la columna.
* @param temp Json Object al cual se agregara el valor de la columna como una propiedad del JSON.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
protected void convertSQLtoJson(ColumnsSQL columna, ResultSet resultado, JSONObject temp) throws SQLException {
String columnName = columna.getCOLUMN_NAME();
String columnType = columna.getTYPE_NAME();
LogsJB.trace("DataType de la columna: " + columna.getTYPE_NAME());
LogsJB.trace("Valor de la columna: " + resultado.getObject(columnName));
if ((StringUtils.containsIgnoreCase(columnType, DataType.NCHAR.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.NVARCHAR.name()))
) {
//Caracteres y cadenas de Texto
temp.put(columnName.toUpperCase(), resultado.getNString(columnName));
} else if ((StringUtils.containsIgnoreCase(columnType, DataType.CHAR.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.LONGVARCHAR.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.VARCHAR.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.TEXT.name()))
) {
//Caracteres y cadenas de Texto
temp.put(columnName.toUpperCase(), resultado.getString(columnName));
} else if ((StringUtils.containsIgnoreCase(columnType, DataType.NUMERIC.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.DECIMAL.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.MONEY.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.SMALLMONEY.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.DOUBLE.name()))) {
//Dinero y numericos que tienen decimales
temp.put(columnName.toUpperCase(), resultado.getDouble(columnName));
} else if ((StringUtils.containsIgnoreCase(columnType, DataType.BIT.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.BOOLEAN.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.BOOL.name()))) {
//Valores Booleanos
Object valor = resultado.getObject(columnName);
LogsJB.trace("Tipo de dato del valor obtenido: " + valor.getClass());
LogsJB.trace("valor obtenido: " + valor);
if ((valor instanceof String)) {
temp.put(columnName.toUpperCase(), Boolean.valueOf((String) valor).booleanValue());
} else if (valor instanceof Integer) {
temp.put(columnName.toUpperCase(), getBooleanfromInt((int) valor));
} else {
temp.put(columnName.toUpperCase(), resultado.getBoolean(columnName));
}
} else if ((StringUtils.containsIgnoreCase(columnType, DataType.SMALLINT.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.TINYINT.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.INTEGER.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.IDENTITY.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.INT.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.SERIAL.name()))) {
//Valores Enteros
temp.put(columnName.toUpperCase(), resultado.getInt(columnName));
} else if ((StringUtils.containsIgnoreCase(columnType, DataType.REAL.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.FLOAT.name()))) {
//Valores Flotantes
temp.put(columnName.toUpperCase(), resultado.getFloat(columnName));
} else if ((StringUtils.containsIgnoreCase(columnType, DataType.BINARY.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.VARBINARY.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.LONGVARBINARY.name()))) {
//Valores binarios
temp.put(columnName.toUpperCase(), resultado.getBytes(columnName));
} else if ((StringUtils.equalsIgnoreCase(columnType, DataType.DATE.name()))) {
//DATE
temp.put(columnName.toUpperCase(), resultado.getDate(columnName));
} else if ((StringUtils.equalsIgnoreCase(columnType, DataType.TIME.name()))) {
//Time
temp.put(columnName.toUpperCase(), resultado.getTime(columnName));
} else if ((StringUtils.containsIgnoreCase(columnType, DataType.TIMESTAMP.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.DATETIME.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.SMALLDATETIME.name()))
|| (StringUtils.containsIgnoreCase(columnType, DataType.DATETIME2.name()))) {
//TimeStamp
temp.put(columnName.toUpperCase(), resultado.getTimestamp(columnName));
} else {
temp.put(columnName.toUpperCase(), resultado.getObject(columnName));
}
}
/**
* Almacena el modelo proporcionado en BD's.
*
* @param modelo Modelo que será insertado o actualizado en BD's
* @param Expresión que hace que el metodo sea generico y pueda ser utilizado por cualquier objeto que herede la Clase JBSqlUtils
* @return La cantidad de filas almacenadas en BD's
* @throws Exception Si sucede una excepción en la ejecución asyncrona de la sentencia en BD's
* captura la excepción y la lanza en el hilo principal
*/
protected CompletableFuture saveModel(T modelo) throws Exception {
modelo.setTaskIsReady(false);
return modelo.validarTableExist(modelo).thenCompose(v -> {
if (modelo.getTableExist()) {
return CompletableFuture.supplyAsync(() -> {
try (Connection connect = modelo.getConnection()) {
StringBuilder sql = new StringBuilder();
StringBuilder sql2 = new StringBuilder();
List campos = modelo.getFieldsOfModel();
List values = new ArrayList<>();
List values2 = new ArrayList<>();
int datos = 0;
List indicemetodos = new ArrayList<>();
if (modelo.getModelExist()) {
// Lógica de actualización
String namePrimaryKey = modelo.getTabla().getClaveprimaria().getCOLUMN_NAME();
sql.append("UPDATE ").append(modelo.getTableName()).append(" SET");
for (int i = 0; i < campos.size(); i++) {
Field campo = campos.get(i);
String columnName = getColumnName(campo);
if (((this.getTimestamps()) && ((StringUtils.equalsIgnoreCase(columnName, this.getCreatedAt()))))
|| (!UtilitiesJB.stringIsNullOrEmpty(namePrimaryKey) && StringUtils.equalsIgnoreCase(namePrimaryKey, columnName))
|| (getValueColumnIsNull(modelo, campo))
|| (!this.getTabla().getColumnsExist().contains(columnName.toUpperCase()))
|| ((!this.getTimestamps()) && ((StringUtils.equalsIgnoreCase(columnName, modelo.getCreatedAt()))
|| (StringUtils.equalsIgnoreCase(columnName, modelo.getUpdateAT()))))
) {
continue;
}
if (StringUtils.containsIgnoreCase(sql, "?")) {
sql.append(", ").append(columnName).append("=?");
} else {
sql.append(" ").append(columnName).append("=?");
}
datos++;
indicemetodos.add(i);
values.add(campo);
}
sql.append(" WHERE ");
int contador = 0;
for (Field columna : campos) {
if ((StringUtils.equalsIgnoreCase(namePrimaryKey, this.getColumnName(columna)) && !this.getValueColumnIsNull(this, columna))
|| (this.getColumnIsIndexValidValue(this, columna))) {
values.add(columna);
contador++;
if (contador > 1) {
sql.append(" AND ");
}
sql.append(this.getColumnName(columna)).append(" = ?");
}
}
} else {
// Lógica de inserción
sql.append("INSERT INTO ").append(modelo.getTableName()).append("(");
for (int i = 0; i < campos.size(); i++) {
Field campo = campos.get(i);
String columnName = getColumnName(campo);
if (((!this.getTimestamps()) && ((StringUtils.equalsIgnoreCase(columnName, modelo.getCreatedAt()))
|| (StringUtils.equalsIgnoreCase(columnName, modelo.getUpdateAT()))))
|| (!this.getTabla().getColumnsExist().contains(columnName.toUpperCase()))
|| (Objects.isNull(FieldUtils.readDeclaredField(modelo, campo.getName(), true)))
) {
continue;
}
datos++;
if (datos > 1) {
sql.append(", ");
}
sql.append(columnName);
values.add(campo);
indicemetodos.add(i);
}
sql.append(") VALUES (");
for (int i = 0; i < values.size(); i++) {
sql.append("?");
int temporal = values.size() - 1;
if (i < temporal) {
sql.append(", ");
} else if (i == temporal) {
sql.append(");");
}
}
if (modelo.getDataBaseType() == DataBase.SQLServer) {
// Obtener cual es la clave primaria de la tabla
int index = sql.indexOf(";");
String namePrimaryKey = modelo.getTabla().getClaveprimaria().getCOLUMN_NAME();
if (index != -1) {
sql = sql.replace(index, index + 1, " SELECT * FROM " + modelo.getTableName() + " WHERE ");
}
int contador = 0;
for (Field columna : campos) {
if (StringUtils.equalsIgnoreCase(namePrimaryKey, this.getColumnName(columna))) {
if (contador > 0) {
sql.append(" AND ");
}
sql.append(namePrimaryKey).append(" = SCOPE_IDENTITY()");
contador++;
}
if ((this.getColumnIsIndexValidValue(this, columna))) {
if (contador > 0) {
sql.append(" AND ");
}
values.add(columna);
sql.append(this.getColumnName(columna)).append(" = ?");
contador++;
}
}
} else if (modelo.getDataBaseType() == DataBase.MySQL) {
// Obtener cual es la clave primaria de la tabla
String namePrimaryKey = modelo.getTabla().getClaveprimaria().getCOLUMN_NAME();
sql2.append("SELECT * FROM ").append(modelo.getTableName()).append(" WHERE ");
int contador = 0;
for (Field columna : campos) {
if (StringUtils.equalsIgnoreCase(namePrimaryKey, this.getColumnName(columna))) {
if (contador > 0) {
sql2.append(" AND ");
}
sql2.append(namePrimaryKey).append(" = LAST_INSERT_ID()");
contador++;
}
if ((this.getColumnIsIndexValidValue(this, columna))) {
if (contador > 0) {
sql2.append(" AND ");
}
values2.add(columna);
sql2.append(this.getColumnName(columna)).append(" = ?");
contador++;
}
}
} else {
// Reemplazar el punto y coma con la nueva cadena
int index = sql.indexOf(";");
if (index != -1) {
sql.replace(index, index + 1, " RETURNING * ;");
}
}
}
PreparedStatement ejecutor = connect.prepareStatement(sql.toString());
//Llena el prepareStatement
LogsJB.debug("Llenara la información de las columnas: " + indicemetodos.size());
int auxiliar = 0;
Integer filas = 0;
if (values.size() > 0) {
for (Field value : values) {
auxiliar++;
String columnName = getColumnName(value);
if ((StringUtils.equalsIgnoreCase(columnName, this.getUpdateAT()))
|| (StringUtils.equalsIgnoreCase(columnName, this.getCreatedAt()))) {
Long datetime = System.currentTimeMillis();
FieldUtils.writeField(modelo, value.getName(), new Timestamp(datetime), true);
}
convertJavaToSQL(modelo, value, ejecutor, auxiliar);
}
LogsJB.info(ejecutor.toString());
if (modelo.getDataBaseType() == DataBase.MySQL && !modelo.getModelExist()) {
ejecutor.executeUpdate();
ejecutor = connect.prepareStatement(sql2.toString());
auxiliar = 0;
for (Field value : values2) {
auxiliar++;
convertJavaToSQL(modelo, value, ejecutor, auxiliar);
}
LogsJB.info(ejecutor.toString());
ResultSet registros = ejecutor.executeQuery();
if (registros.next()) {
procesarResultSetOneResult(modelo, registros);
filas++;
}
} else if (modelo.getModelExist()) {
filas = ejecutor.executeUpdate();
} else {
ResultSet registros = ejecutor.executeQuery();
if (registros.next()) {
procesarResultSetOneResult(modelo, registros);
filas++;
}
}
}
LogsJB.info("Filas afectadas en BD's': " + filas + " " + this.getTableName());
modelo.closeConnection(connect);
modelo.setTaskIsReady(true);
modelo.setModelExist(true);
return filas;
} catch (Exception e) {
LogsJB.fatal("Excepción disparada en el método que Guarda el modelo en la BD's, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
modelo.setTaskIsReady(true);
return 0;
}
});
} else {
LogsJB.warning("Tabla correspondiente al modelo no existe en BD's por esa razón no se pudo almacenar el Registro");
modelo.setTaskIsReady(true);
return CompletableFuture.completedFuture(0);
}
});
}
/**
* Elimina la información del modelo proporcionado en BD's
*
* @param modelo Modelo del cual se desea eliminar la información en BD's
* @param Expresión que hace que el metodo sea generico y pueda ser utilizado por cualquier
* objeto que herede la Clase JBSqlUtils
* @return La cantidad de filas eliminadas en BD's
* @throws Exception Si sucede una excepción en la ejecución asyncrona de la sentencia en BD's
* captura la excepción y la lanza en el hilo principal
*/
protected CompletableFuture deleteModel(T modelo) throws Exception {
modelo.setTaskIsReady(false);
return modelo.validarTableExist(modelo).thenCompose(v -> {
if (modelo.getTableExist()) {
return CompletableFuture.supplyAsync(() -> {
try (Connection connect = modelo.getConnection()) {
String namePrimaryKey = modelo.getTabla().getClaveprimaria().getCOLUMN_NAME();
StringBuilder sql = new StringBuilder("DELETE FROM ").append(modelo.getTableName());
List columnas = this.getFieldsOfModel();
List values = new ArrayList<>();
boolean whereAdded = false;
for (Field columna : columnas) {
if ((StringUtils.equalsIgnoreCase(namePrimaryKey, this.getColumnName(columna)) && !this.getValueColumnIsNull(this, columna))
|| (this.getColumnIsIndexValidValue(this, columna))) {
values.add(columna);
if (whereAdded) {
sql.append(" AND ");
} else {
sql.append(" WHERE ");
whereAdded = true;
}
sql.append(this.getColumnName(columna)).append(" = ?");
}
}
sql.append(";");
PreparedStatement ejecutor = connect.prepareStatement(sql.toString());
int auxiliar = 0;
Integer filas = 0;
LogsJB.debug("Colocara la información del where: " + auxiliar);
if (!values.isEmpty()) {
for (Field value : values) {
auxiliar++;
convertJavaToSQL(this, value, ejecutor, auxiliar);
}
LogsJB.info(ejecutor.toString());
filas = ejecutor.executeUpdate();
}
LogsJB.info("Filas eliminadas: " + filas);
modelo.closeConnection(connect);
modelo.setTaskIsReady(true);
return filas;
} catch (Exception e) {
LogsJB.fatal("Excepción disparada en el método que Guarda el modelo en la BD's, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
modelo.setTaskIsReady(true);
return 0;
}
});
} else {
LogsJB.warning("Tabla correspondiente al modelo no existe en BD's por esa razón no se pudo eliminar el Registro " + this.getClass().getSimpleName());
modelo.setTaskIsReady(true);
return CompletableFuture.completedFuture(0);
}
});
}
/**
* Obtiene una instancia nueva del tipo de modelo que se envía como parametro
*
* @param modelo Tipo de objeto que se desea instanciar
* @param Expresión que hace que el metodo sea generico y pueda ser utilizado por cualquier
* objeto que herede la Clase JBSqlUtils
* @return Retorna la nueva instancia del modelo creada
*/
public T obtenerInstanciaOfModel(T modelo) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
T temp;
if (modelo.getGetPropertySystem()) {
temp = (T) modelo.getClass().newInstance();
temp.llenarPropertiesFromModel(temp);
} else {
Constructor constructor = modelo.getClass().getConstructor(Boolean.class);
temp = (T) constructor.newInstance(false);
temp.llenarPropertiesFromModel(modelo);
}
return temp;
}
/**
* Valida si el modelo ya conoce si su tabla existe en BD's de lo contrario ejecuta este metodo para asegurarse que
* obtenga la información de BD's
*
* @param modelo Modelo que se desea validar si su tabla existe en BD's
* @param
* @throws Exception Si sucede una excepción en la ejecución de esta tarea la lanza al metodo que la invoco
*/
protected CompletableFuture validarTableExist(T modelo) throws Exception {
if (!modelo.getTableExist()) {
return modelo.tableExist().thenAccept(
exist -> modelo.setTableExist(exist)
);
}
return CompletableFuture.completedFuture(null);
}
/**
* Obtiene un nuevo modelo del tipo de modelo proporcionado para procesar el ResultSet
* con la información de BD's
*
* @param modelo Modelo que invoca el metodo.
* @param registros Resulset que contiene la información obtenida de BD's
* @param Expresión que hace que el metodo sea generico y pueda ser utilizado por cualquier
* objeto que herede la Clase JBSqlUtils
* @return Retorna un nuevo modelo del tipo de modelo proporcionado para procesar el ResultSet
* con la información de BD's
* @throws InstantiationException Lanza esta excepción si ocurre un error al crear una nueva instancia
* del tipo de modelo proporcionado
* @throws SQLException Lanza esta excepción de suceder algún problema con el ResultSet
* @throws InvocationTargetException Lanza esta excepción si hubiera algún problema al invocar el metodo Set
* @throws IllegalAccessException Lanza esta excepción si hubiera algún problema al invocar el metodo Set
* @throws DataBaseUndefind Lanza esta excepción si en las propiedades del sistema no esta definida el tipo de
* BD's a la cual se conectara el modelo.
* @throws PropertiesDBUndefined Lanza esta excepción si en las propiedades del sistema no estan definidas las
* propiedades de conexión necesarias para conectarse a la BD's especificada.
* @throws NoSuchMethodException Lanza esta excepción si el modelo no posee el metodo que se invocara
*/
protected T procesarResultSet(T modelo, ResultSet registros) throws InstantiationException, IllegalAccessException, InvocationTargetException, SQLException, DataBaseUndefind, PropertiesDBUndefined, NoSuchMethodException {
T temp = modelo.obtenerInstanciaOfModel(modelo);
temp.setTabla(modelo.getTabla());
temp.setTableExist(modelo.getTableExist());
temp.setTableName(modelo.getTableName());
temp.setModelExist(true);
LogsJB.debug("Obtuvo un resultado de BD's, procedera a llenar el modelo " + temp.getClass().getSimpleName());
LogsJB.trace("obtuvo los métodos set");
LogsJB.debug("Cantidad de columnas : " + temp.getTabla().getColumnas().size());
List fields = new ArrayList<>(temp.getFieldsOfModel());
LogsJB.trace("Inicializa el array list de los campos del modelo");
LogsJB.debug("Cantidad de campos set: " + fields.size());
Map fieldMap = new HashMap<>();
for (Field field : fields) {
String fieldName = getColumnName(field);
fieldMap.put(fieldName.toLowerCase(), field);
}
// Llena la información del modelo
for (ColumnsSQL columna : temp.getTabla().getColumnas()) {
String columnName = columna.getCOLUMN_NAME();
LogsJB.trace("Columna : " + columnName);
// Buscar el campo en el mapa
Field field = fieldMap.get(columnName.toLowerCase());
if (field != null) {
LogsJB.trace("Nombre de la columna, nombre del campo a setear el valor: " + columnName + " " + field.getName());
convertSQLtoJava(columna, registros, field, temp);
}
}
return temp;
}
/**
* Llena el modelo proporcionado con la Información Obtenida de BD's
*
* @param modelo Modelo que invoca el metodo.
* @param registros Resulset que contiene la información obtenida de BD's
* @throws InstantiationException Lanza esta excepción si ocurre un error al crear una nueva instancia
* del tipo de modelo proporcionado
* @throws SQLException Lanza esta excepción de suceder algún problema con el ResultSet
* @throws InvocationTargetException Lanza esta excepción si hubiera algún problema al invocar el metodo Set
* @throws IllegalAccessException Lanza esta excepción si hubiera algún problema al invocar el metodo Set
*/
protected void procesarResultSetOneResult(T modelo, ResultSet registros) throws InstantiationException, IllegalAccessException, InvocationTargetException, SQLException {
modelo.setModelExist(true);
LogsJB.debug("Obtuvo un resultado de BD's, procedera a llenar el modelo " + modelo.getTableName());
LogsJB.debug("Cantidad de columnas : " + modelo.getTabla().getColumnas().size());
// Cachear los campos y crear un mapa para búsqueda rápida
List fields = new ArrayList<>(modelo.getFieldsOfModel());
LogsJB.trace("Inicializa el array list de los campos del modelo");
LogsJB.debug("Cantidad de campos set: " + fields.size());
Map fieldMap = new HashMap<>();
for (Field field : fields) {
String fieldName = getColumnName(field);
fieldMap.put(fieldName.toLowerCase(), field);
}
//Llena la información del modelo
for (ColumnsSQL columna : modelo.getTabla().getColumnas()) {
String columnName = columna.getCOLUMN_NAME();
LogsJB.trace("Columna : " + columnName);
// Buscar el campo en el mapa
Field field = fieldMap.get(columnName.toLowerCase());
if (field != null) {
LogsJB.trace("Nombre de la columna, nombre del campo a setear el valor: " + columnName + " " + field.getName());
convertSQLtoJava(columna, registros, field, modelo);
}
}
}
/**
* Obtiene un Json Object con las columnas solicitadas como propiedades del json con sus respectivos valores
*
* @param registros ResultSet del cual se obtendran los valores de las columnas
* @param columnMetadata List of ColumnsSQL containing metadata of the columns
* @return Retorna un Json Object con las columnas solicitadas como propiedades del json con sus respectivos valores
* @throws SQLException Lanza esta excepción si sucede algún error al obtener el valor de cada una de las columnas solicitadas
*/
protected JSONObject procesarResultSetJSON(ResultSet registros, List columnMetadata) throws SQLException {
JSONObject temp = new JSONObject();
LogsJB.debug("Obtuvo un resultado de BD's, procedera a llenar el JSON");
for (ColumnsSQL columna : columnMetadata) {
String columnName = columna.getCOLUMN_NAME();
String columnType = columna.getTYPE_NAME();
LogsJB.trace("Columna : " + columnName);
LogsJB.trace("Tipo de dato : " + columnType);
this.convertSQLtoJson(columna, registros, temp);
}
return temp;
}
/**
* Crea la tabla correspondiente al modelo en BD's si esta no existe.
*
* @return True si la tabla correspondiente al modelo en BD's no existe y fue creada exitosamente,
* False si la tabla correspondiente al modelo ya existe en BD's
* @throws Exception Si sucede una excepción en la ejecución asincrona de la sentencia en BD's lanza esta excepción
*/
public Boolean createTable() throws Exception {
CompletableFuture future = tableExist().thenCompose(exists -> {
if (exists) {
LogsJB.info("La tabla correspondiente al modelo ya existe en la BD's, por lo cual no será creada.");
return CompletableFuture.completedFuture(false);
} else {
return CompletableFuture.supplyAsync(() -> {
StringBuilder sql = new StringBuilder("CREATE TABLE ").append(this.getTableName()).append("(");
List fields;
List foreignKeys = new ArrayList<>();
Connection connect = null;
Statement ejecutor = null;
try {
fields = this.getFieldsOfModel().stream()
.filter(field -> !Objects.isNull(getDataTypeSQL(field)))
.sorted(Comparator.comparingInt(field -> getDataTypeSQL(field).getOrden()))
.collect(Collectors.toList());
int datos = 0;
for (Field campo : fields) {
String columnName = getColumnName(campo);
DataType columnType = getDataTypeSQL(campo);
ForeignKey temp = getForeignKey(campo);
if (!Objects.isNull(temp)) {
foreignKeys.add(temp);
}
if (columnType == DataType.TIMESTAMP && this.getDataBaseType() == DataBase.SQLServer) {
columnType = DataType.DATETIME;
}
Constraint[] columnRestriccion = getConstraints(campo);
String restricciones = "";
String defaultValue = getColumnDefaultValue(campo);
String size = getSize(campo);
if (Arrays.asList(DataBase.PostgreSQL, DataBase.MySQL, DataBase.SQLite, DataBase.MariaDB).contains(this.getDataBaseType())
&& columnType == DataType.BIT) {
columnType = DataType.BOOLEAN;
}
if (this.getDataBaseType() == DataBase.SQLServer && columnType == DataType.BOOLEAN) {
columnType = DataType.BIT;
}
if (this.getDataBaseType() == DataBase.PostgreSQL && columnType == DataType.DOUBLE) {
size = "";
}
if (this.getDataBaseType() == DataBase.SQLServer && columnType == DataType.DOUBLE) {
columnType = DataType.REAL;
}
if (this.getDataBaseType() == DataBase.MySQL && (columnType == DataType.TEXT || columnType == DataType.JSON)) {
defaultValue = null;
}
if (this.getDataBaseType() == DataBase.SQLServer && columnType == DataType.BIT && !stringIsNullOrEmpty(defaultValue)) {
defaultValue = "" + getIntFromBoolean(Boolean.valueOf(defaultValue));
}
String tipo_de_columna = stringIsNullOrEmpty(size) ? columnType.name() : columnType.name() + "(" + size + ")";
if (this.getDataBaseType() == DataBase.PostgreSQL && columnType == DataType.DOUBLE) {
tipo_de_columna = tipo_de_columna.replace("DOUBLE", "DOUBLE PRECISION");
}
if (!Objects.isNull(columnRestriccion)) {
for (Constraint restriccion : columnRestriccion) {
if (this.getDataBaseType() == DataBase.PostgreSQL && restriccion == Constraint.AUTO_INCREMENT) {
tipo_de_columna = DataType.SERIAL.name();
} else if (this.getDataBaseType() == DataBase.SQLServer && restriccion == Constraint.AUTO_INCREMENT) {
restricciones += DataType.IDENTITY + " ";
} else if (this.getDataBaseType() == DataBase.SQLite && restriccion == Constraint.AUTO_INCREMENT) {
restricciones = restricciones;
} else if (restriccion == Constraint.DEFAULT && stringIsNullOrEmpty(defaultValue)) {
continue;
} else if (restriccion == Constraint.DEFAULT && !stringIsNullOrEmpty(defaultValue)) {
restricciones += restriccion.getRestriccion() + " " + defaultValue + " ";
} else {
restricciones += restriccion.getRestriccion() + " ";
}
}
}
if (!this.getTimestamps() && (StringUtils.equalsIgnoreCase(columnName, this.getCreatedAt())
|| StringUtils.equalsIgnoreCase(columnName, this.getUpdateAT()))) {
continue;
}
if (datos++ > 0) {
sql.append(", ");
}
sql.append(columnName).append(" ").append(tipo_de_columna).append(" ").append(restricciones);
}
for (ForeignKey foreignKey : foreignKeys) {
sql.append(", FOREIGN KEY (").append(foreignKey.columName()).append(") REFERENCES ")
.append(foreignKey.tableReference()).append("(").append(foreignKey.columnReference()).append(")");
for (Actions accion : foreignKey.actions()) {
sql.append(accion.operacion().getOperador()).append(accion.action().getOperacion());
}
}
sql.append(");");
connect = this.getConnection();
ejecutor = connect.createStatement();
LogsJB.info(sql.toString());
if (!ejecutor.execute(sql.toString())) {
LogsJB.info("Sentencia para crear tabla de la BD's ejecutada exitosamente");
LogsJB.info("Tabla " + this.getTableName() + " Creada exitosamente");
this.setTableExist(true);
this.refresh();
return true;
}
} catch (Exception e) {
LogsJB.fatal("Excepción disparada en el método que Crea la tabla correspondiente al modelo, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
return false;
} finally {
if (ejecutor != null) {
try {
ejecutor.close();
} catch (SQLException e) {
LogsJB.error("Error al cerrar el Statement: " + e.getMessage());
}
}
if (connect != null) {
this.closeConnection(connect);
}
}
return false;
});
}
});
Boolean resultado = future.join();
return resultado;
}
/**
* Elimina la tabla correspondiente al modelo en BD's
*
* @return True si la tabla correspondiente al modelo en BD's existe y fue eliminada, de no existir la tabla correspondiente
* en BD's retorna False.
* @throws Exception Si sucede una excepción en la ejecución asincrona de la sentencia en BD's lanza esta excepción
*/
public Boolean dropTableIfExist() throws Exception {
CompletableFuture future = tableExist().thenCompose(exists -> {
if (exists) {
return CompletableFuture.supplyAsync(() -> {
StringBuilder sql = new StringBuilder();
Connection connect = null;
Statement ejecutor = null;
try {
if (this.getDataBaseType() == DataBase.SQLServer) {
sql.append("if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = '")
.append(this.getTableName())
.append("' AND TABLE_SCHEMA = 'dbo')\n")
.append(" drop table dbo.")
.append(this.getTableName());
} else {
sql.append("DROP TABLE IF EXISTS ").append(this.getTableName());
}
LogsJB.info(sql.toString());
connect = this.getConnection();
ejecutor = connect.createStatement();
if (!ejecutor.execute(sql.toString())) {
LogsJB.info("Sentencia para eliminar tabla de la BD's ejecutada exitosamente");
LogsJB.info("Tabla " + this.getTableName() + " Eliminada exitosamente");
this.setTableExist(false);
this.refresh();
return true;
}
} catch (Exception e) {
LogsJB.fatal("Excepción disparada en el método que Elimina la tabla correspondiente al modelo, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
return false;
} finally {
if (ejecutor != null) {
try {
ejecutor.close();
} catch (SQLException e) {
LogsJB.error("Error al cerrar el Statement: " + e.getMessage());
}
}
if (connect != null) {
this.closeConnection(connect);
}
}
return false;
});
} else {
LogsJB.info("Tabla correspondiente al modelo no existe en BD's por eso no pudo ser eliminada");
return CompletableFuture.completedFuture(false);
}
});
return future.join();
}
/**
* Crea la tabla solicitada correspondiente al modelo con las columnas especificadas como parametro
*
* @param columnas Lista de columnas que se desea sean creadas por JBSqlUtils
* @return Retorna True si logra crear la tabla, False en caso que la tabla ya exista en BD's o que
* haya sucedido un error al momento de ejecutar la sentencia SQL
* @throws Exception Si sucede una excepción en la ejecución asincrona de la sentencia en BD's lanza esta excepción
*/
protected Boolean crateTableJSON(List columnas) throws Exception {
CompletableFuture> future = tableExist().thenCompose(exists -> {
if (exists) {
LogsJB.info("La tabla correspondiente al modelo ya existe en la BD's, por lo cual no será creada.");
return CompletableFuture.completedFuture(new ResultAsync<>(false, null));
} else {
return CompletableFuture.supplyAsync(() -> {
StringBuilder sql = new StringBuilder("CREATE TABLE ").append(this.getTableName()).append("(");
Connection connect = null;
Statement ejecutor = null;
try {
LogsJB.debug("Comienza a ordenar la lista");
columnas.sort((columna1, columna2) -> {
try {
LogsJB.trace("Columnas a evaluar: " + columna1.getName() + " " + columna2.getName());
if (columna1.getDataTypeSQL().getOrden() > columna2.getDataTypeSQL().getOrden()) {
LogsJB.trace("Columna de metodo 1 es mayor");
return 1;
} else if (columna2.getDataTypeSQL().getOrden() > columna1.getDataTypeSQL().getOrden()) {
LogsJB.trace("Columna de metodo 2 es mayor");
return -1;
} else {
LogsJB.trace("Columnas son iguales");
return 0;
}
} catch (Exception e) {
LogsJB.fatal("Excepción disparada al tratar de ordenar los metodos get de la lista, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
}
return 0;
});
LogsJB.debug("Termino de ordenar la lista");
int datos = 0;
for (Column columnsSQL : columnas) {
String columnName = columnsSQL.getName();
DataType columnType = columnsSQL.getDataTypeSQL();
if ((columnType == DataType.TIMESTAMP) && (this.getDataBaseType() == DataBase.SQLServer)) {
columnType = DataType.DATETIME;
columnsSQL.setDataTypeSQL(DataType.DATETIME);
}
Constraint[] columnRestriccion = columnsSQL.getRestriccion();
String restricciones = "";
if (((this.getDataBaseType() == DataBase.PostgreSQL) || (this.getDataBaseType() == DataBase.MySQL) || (this.getDataBaseType() == DataBase.SQLite) || (this.getDataBaseType() == DataBase.MariaDB)) && (columnType == DataType.BIT)) {
columnsSQL.setDataTypeSQL(DataType.BOOLEAN);
}
if ((this.getDataBaseType() == DataBase.SQLServer) && columnType == DataType.BOOLEAN) {
columnsSQL.setDataTypeSQL(DataType.BIT);
}
String tipo_de_columna = columnsSQL.columnToString();
if (!Objects.isNull(columnRestriccion)) {
for (Constraint restriccion : columnRestriccion) {
if ((DataBase.PostgreSQL == this.getDataBaseType()) && (restriccion == Constraint.AUTO_INCREMENT)) {
tipo_de_columna = DataType.SERIAL.name();
} else if ((DataBase.SQLServer == this.getDataBaseType()) && (restriccion == Constraint.AUTO_INCREMENT)) {
restricciones = restricciones + DataType.IDENTITY + " ";
} else if ((DataBase.SQLite == this.getDataBaseType()) && (restriccion == Constraint.AUTO_INCREMENT)) {
restricciones = restricciones;
} else if (restriccion == Constraint.DEFAULT) {
restricciones = restricciones + restriccion.getRestriccion() + " " + columnsSQL.getDefault_value() + " ";
} else {
restricciones = restricciones + restriccion.getRestriccion() + " ";
}
}
}
if ((!this.getTimestamps()) && ((StringUtils.equalsIgnoreCase(columnName, "created_at")) || (StringUtils.equalsIgnoreCase(columnName, "updated_at")))) {
continue;
}
String columna = columnName + " " + tipo_de_columna + " " + restricciones;
datos++;
if (datos > 1) {
sql.append(", ");
}
sql.append(columna);
}
sql.append(");");
connect = this.getConnection();
ejecutor = connect.createStatement();
LogsJB.info(sql.toString());
if (!ejecutor.execute(sql.toString())) {
LogsJB.info("Sentencia para crear tabla de la BD's ejecutada exitosamente");
LogsJB.info("Tabla " + this.getTableName() + " Creada exitosamente");
this.refresh();
return new ResultAsync<>(true, null);
}
} catch (Exception e) {
LogsJB.fatal("Excepción disparada en el método que Crea la tabla solicitada, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
return new ResultAsync<>(false, e);
} finally {
if (ejecutor != null) {
try {
ejecutor.close();
} catch (SQLException e) {
LogsJB.fatal("Error al cerrar el Statement: " + ExceptionUtils.getStackTrace(e));
}
}
if (connect != null) {
this.closeConnection(connect);
}
}
return new ResultAsync<>(false, null);
});
}
});
ResultAsync resultado = future.join();
if (!Objects.isNull(resultado.getException())) {
throw resultado.getException();
}
return resultado.getResult();
}
/**
* Llena las propiedades de conexión de un modelo desde otro
*
* @param proveedor Modelo desde el que se obtendran las propiedades de conexión
* @param Modelo a llenar
* @param Tipo de dato del invocador
*/
public void llenarPropertiesFromModel(G proveedor) {
try {
this.setGetPropertySystem(proveedor.getGetPropertySystem());
// Crear un set con los nombres de los métodos que queremos filtrar
Set metodosProveedorNombres = Set.of("getDataBaseType", "getHost", "getPort", "getUser", "getPassword", "getBD", "getPropertisURL");
Set metodosReciberNombres = Set.of("setDataBaseType", "setHost", "setPort", "setUser", "setPassword", "setBD", "setPropertisURL");
// Obtener los métodos de la clase actual y del proveedor
Method[] metodosClaseActual = this.getClass().getMethods();
Method[] metodosProveedor = proveedor.getClass().getMethods();
// Crear un mapa para emparejar los métodos
// Crear un mapa para emparejar los métodos
Map metodosReciberMap = Arrays.stream(metodosClaseActual)
.filter(metodo -> metodosReciberNombres.contains(metodo.getName()) && metodo.getParameterCount() == 1)
.collect(Collectors.toMap(
metodo -> StringUtils.removeStartIgnoreCase(metodo.getName(), "set"),
metodo -> metodo
));
// Iterar sobre los métodos del proveedor y emparejar con los métodos del recibidor
for (Method metodoProveedor : metodosProveedor) {
String nombreMetodo = metodoProveedor.getName();
if (metodosProveedorNombres.contains(nombreMetodo)) {
String nombreMetodoProveedor = StringUtils.removeStartIgnoreCase(nombreMetodo, "get");
Method metodoReciber = metodosReciberMap.get(nombreMetodoProveedor);
if (metodoReciber != null) {
// Llena el recibidor con la información de las propiedades de conexión
metodoReciber.invoke(this, metodoProveedor.invoke(proveedor));
}
}
}
} catch (Exception e) {
LogsJB.fatal("Excepción disparada al llenar el modelo, con la info del modelo proporcionado, " + "Trace de la Excepción : " + ExceptionUtils.getStackTrace(e));
}
}
/**
* en esta funcion se obtiene el nombre de la columna de un campo,
* si tiene anotacion el campo, va devolver el name
* si la anotacion es null o vacio, devolvera el nombre del campo
*
* @param field maneja un parametro de tipo objeto field
* @return retorna el nombre de la columna estipulado en el if
*/
private String getColumnName(Field field) {
//Obtengo la información de la columna
ColumnDefined columnDefined = field.getAnnotation(ColumnDefined.class);
if ((Objects.isNull(columnDefined)) || stringIsNullOrEmpty(columnDefined.name())) {
//No tiene anotación o el valor seteado
return field.getName();
} else {
//Tiene anotación
return columnDefined.name();
}
}
/**
* este metodo verifica si tiene anotacion index es true y si es null es false.
*
* @param field parametro tipo objeto field
* @return retorna una columna
*/
private Boolean getColumnIsIndex(Field field) {
//Obtiene si la columna es un Index
return !Objects.isNull(field.getAnnotation(Index.class));
}
/**
* este metodo comprueba que los campos que vienen tengan indices de valor adecuado.
*
* @param model parametro de la entidad que contiene los datos model
* @param field parametro field que es de tipo objeto
* @return retorna la columana q es tipo inde y si es nula
* @throws IllegalAccessException maneja la ecepcion cuando intentan acceder a un campo privado
*/
private Boolean getColumnIsIndexValidValue(Object model, Field field) throws IllegalAccessException {
//Obtiene si la columna es un Index
return this.getColumnIsIndex(field) && !this.getValueColumnIsNull(model, field);
}
/**
* este metodo se encarga de verificar si el valor de un campo especifico de un model es null
*
* @param model parametor del objeto donde se quiere leer el campo
* @param field parametro del nombre del campo que se desea leer
* @return retorna un valor, donde verifica si el valor es null
* @throws IllegalAccessException
*/
private Boolean getValueColumnIsNull(Object model, Field field) throws IllegalAccessException {
//Obtiene si la columna es un Index
return Objects.isNull(FieldUtils.readDeclaredField(model, field.getName(), true));
}
/**
* este metodo se utiliza para obtener el valor de un campo especifico de un objeto,
* donde la diferencia es que este campo puede ser privado.
*
* @param model es el objeto desde el cual se leera el valor.
* @param field es el parametro atributo del cual se recupera el valor.
* @return retorna el nombre obtenido
* @throws IllegalAccessException maneja la ecepcion
*/
private Object getValueColumn(Object model, Field field) throws IllegalAccessException {
//Obtiene si la columna es un Index
return FieldUtils.readDeclaredField(model, field.getName(), true);
}
/**
* Este metodo permite determinar el valor inicial o por defecto de un campo que esta
* siendo mapeado a una BD.
*
* @param field es el campo del cual se recupera el valor.
* @return retorna la columana definida con una cadena string
*/
private String getColumnDefaultValue(Field field) {
//Obtengo la información de la columna
ColumnDefined columnDefined = field.getAnnotation(ColumnDefined.class);
//Tiene anotación
if (Objects.isNull(columnDefined)) {
return null;
}
return columnDefined.default_value();
}
/**
* con este metodo se logra conocer las restricciones de tamaño de un campo que esta siendo mapeado.
*
* @param field campo tipo field del cual se desea obtener el tamaño
* @return retorna una cadena string
*/
private String getSize(Field field) {
//Obtengo la información de la columna
ColumnDefined columnDefined = field.getAnnotation(ColumnDefined.class);
//Tiene anotación
if (Objects.isNull(columnDefined)) {
return null;
}
return columnDefined.size();
}
/**
* este metodo es utilizado para obtener las restricciones definidas para determinada columna
* donde denota la anotacion ColumnDefined
*
* @param field campo del cual se desea obtener las restricciones
* @return si el campo no tiene anotacion, retorna null
*/
private Constraint[] getConstraints(Field field) {
//Obtengo la información de la columna
ColumnDefined columnDefined = field.getAnnotation(ColumnDefined.class);
//Tiene anotación
if (Objects.isNull(columnDefined)) {
return null;
}
return columnDefined.constraints();
}
/**
* este metodo se utiliza para generar una cadena que representa el tipo de dato SQL,
*
* @param field es el campo del cual se desea obtener el dato SQL como cadena
* @return retorna el tipo de dato, en uno sin importar el tamaño y el otro return si retorna el tamaño de la cadena.
*/
private String getDataTypeSQLToString(Field field) {
//Obtengo la información de la columna
ColumnDefined columnDefined = field.getAnnotation(ColumnDefined.class);
//Tiene anotación
if (Objects.isNull(columnDefined) || Objects.isNull(columnDefined.dataTypeSQL())) {
return null;
}
DataType dataType = columnDefined.dataTypeSQL();
if (stringIsNullOrEmpty(this.getSize(field))) {
return dataType.name();
} else {
return dataType.name() + "(" + this.getSize(field) + ")";
}
}
/**
* este metodo obtiene el tipo de dato SQL de un campo,
*
* @param field es el campo del cual se desea obtener el tipo de dato
* @return retorna un objeto tipo datatype
*/
private DataType getDataTypeSQL(Field field) {
//Obtengo la información de la columna
ColumnDefined columnDefined = field.getAnnotation(ColumnDefined.class);
//Tiene anotación
if (Objects.isNull(columnDefined) || Objects.isNull(columnDefined.dataTypeSQL())) {
return null;
}
return columnDefined.dataTypeSQL();
}
/**
* este metodo devuelve la informacion sobre la clave foranea que se encuentra definida
* en un campo especifico.
*
* @param field campo del cual se desean obtener los datos
* @return rertorna null si no encuentra anotacion sobre la llave foranea
*/
private ForeignKey getForeignKey(Field field) {
//Obtengo la información de la columna
ColumnDefined columnDefined = field.getAnnotation(ColumnDefined.class);
//Tiene anotación
if (Objects.isNull(columnDefined) || stringIsNullOrEmpty(columnDefined.foreignkey().columName())
|| stringIsNullOrEmpty(columnDefined.foreignkey().tableReference())
|| stringIsNullOrEmpty(columnDefined.foreignkey().columnReference())) {
return null;
}
return columnDefined.foreignkey();
}
/**
* Ordena la consula sql de acuerdo al estandar de consulta SQL
* @param query Consulta SQL que se desea ordenar
* @param modelo Es el invocador de los metodos que se estan utilizando
* @return Retorna un string que representa la consulta SQL ordenada
* @param
* @throws DataBaseUndefind Lanza esta excepción cuando no se a configurado la BD's a la cual se conectara el modelo
* el usuario de la librería es el encargado de setear el tipo de BD's a la cual se conectara el modelo, asi mismo de ser lanzada
* esta excepción, poder manejarla.
*/
protected String generateOrderSQL(String query, T modelo) throws DataBaseUndefind {
//Si es sql server y trae la palabra limit verificara y modificara la sentencia
if (modelo.getDataBaseType() == DataBase.SQLServer) {
if (StringUtils.containsIgnoreCase(query, "LIMIT")) {
String temporal_limite = StringUtils.substringAfterLast(query, "LIMIT").replace(";", "").trim();
String select = "SELECT TOP " + temporal_limite + " * FROM ";
query = query.replace("SELECT * FROM ", select).replace("LIMIT " + temporal_limite, "");
LogsJB.debug("Se modifico la sentencia SQL para que unicamente obtenga la cantidad de " +
"registros especificados por el usuario: " + query);
}
}
// Insertar la cláusula GROUP BY en la posición correcta
int whereIndex = query.indexOf(" WHERE ");
int havingIndex = query.indexOf(" HAVING ");
int orderByIndex = query.indexOf(" ORDER BY ");
int limitIndex = query.indexOf(" LIMIT ");
int groupByIndex = query.indexOf(" GROUP BY ");
int groupByEndIndex = query.indexOf(";", groupByIndex);
if (groupByIndex != -1 && groupByEndIndex != -1) {
String groupByClause = query.substring(groupByIndex, groupByEndIndex + 1);
query = query.substring(0, groupByIndex) + query.substring(groupByEndIndex + 1);
if (whereIndex != -1) {
query = query.substring(0, whereIndex + 7) + groupByClause + query.substring(whereIndex + 7);
} else if (havingIndex != -1) {
query = query.substring(0, havingIndex) + groupByClause + query.substring(havingIndex);
} else if (orderByIndex != -1) {
query = query.substring(0, orderByIndex) + groupByClause + query.substring(orderByIndex);
} else if (limitIndex != -1) {
query = query.substring(0, limitIndex) + groupByClause + query.substring(limitIndex);
} else {
query = query + groupByClause;
}
}
return query;
}
}