AYUDA VALIDACION

Iniciado por taos19, 20 Marzo 2014, 22:27 PM

0 Miembros y 1 Visitante están viendo este tema.

taos19

Buen Dia Amigos

Tengo este metodo que verifica despues de un tiempo si el usuario puede seguir teniendo acceso al programa.

Este compara dos campos de una base de datos para ver si se puede ingresar al programa o no.

Alguien me podria explicar su funcionamiento y como puedo personalizar el tiempo.

Código (java) [Seleccionar]
public boolean validarlicencia()
throws Exception
   {
     String sql = "SELECT ID1, ID2 FROM TB_CIV_TMP WHERE ID1 = ?";
     List<Map> obj = findMapBySQLParam(sql, new String[] { "id1", "id2" }, new Object[] { "202cb962ac59075b964b07152d234b70" });
     if ((null == obj) || (obj.size() <= 0)) {
       return false;
     }
     Object id2 = ((Map)obj.get(0)).get("id2");
     if (null == id2)
     {
       Calendar cal = Calendar.getInstance();
       cal.add(5, 80);
       Long var1 = Long.valueOf(cal.getTime().getTime());
       sql = "UPDATE TB_CIV_TMP SET ID2 = ?";
       executeUpdateSQLParam(sql, new Object[] { var1 });
       return true;
     }
     Calendar cal = Calendar.getInstance();
     Long var1 = Long.valueOf(Long.parseLong("" + id2));
     Long var2 = Long.valueOf(cal.getTime().getTime());
     if (var2.longValue() > var1.longValue())
     {
       sql = "DELETE FROM TB_CIV_TMP";
       executeUpdateSQL(sql);
       return false;
     }
     return true;
   }


Gracias de antemano

Mitsu

#1
Hola, vamos a hacer un análisis de este algoritmo que a simple vista no entiendo nada xD

Esta línea obtiene los campos ID1, ID2 de la tabla TB_CIV_TEMP cuando el ID1 es desconocido, es decir luego se seteará el parámetro de condición.
Código (=java) [Seleccionar]

String sql = "SELECT ID1, ID2 FROM TB_CIV_TMP WHERE ID1 = ?";


Luego hace uso de un método del cual no podemos ver nada pero al parecer devuelve fechas en milisegundos (para poder compararse luego). Este método recibe 3 parámetros: La query, un array String y un array Object.

Dado que no puedo ver el código de éste método, creo que no hace falta decirte que no entiendo ni un carajo para qué sirve xD

Código (=java) [Seleccionar]

List<Map> obj = findMapBySQLParam(sql, new String[] { "id1", "id2" }, new Object[] { "202cb962ac59075b964b07152d234b70" });


Ahora, podemos deducir que el método findMapBySQLParam() concatenerá algún valor (alguna fecha en milisegundos quizás) con la query y hará la consulta. Por otro lado, si no se puede realizar la consulta o no hay coincidencias con la consulta, la lista puede ser nula (si no se ha podido realizar la consulta) o vacía (si no hay coincidencias). Si ésto llegara a pasar, devuelve false y termina el método.

Crea un objeto Object y le asigna el valor de la llave "id2" del primer Map de la lista recibida.

Código (=java) [Seleccionar]

// obj.get(0) -> obtiene el primer elemento de la lista. En este caso el primer Map
// .get("id2") -> obtiene el valor asociado a la llave "id2"
Object id2 = (Map) obj.get(0).get("id2");


Si el valor es nulo, es decir no hay una llave con ese identificador lo crea:

Código (=java) [Seleccionar]

Calendar cal = Calendar.getInstance(); // obtiene una instancia Calendar
// el primer parametro debe ser una constante. 5 equivale a Calendar.DAY
// el segundo parametro le suma 80 al tipo de dato de la constante. Ej.,
// si es Calendar.DAY y hoy estamos 20, adelanta la fecha en 80 dias.
call.add(5,80);
// Obtiene la fecha avanzada en milisegundos
Long var1 = Long.valueOf(cal.getTime().getTime());
// actualiza el campo ID2 con la fecha avanzada en milisegundos (al parecer)
sql = "UPDATE TB_CIV_TMP SET ID2 = ?";
executeUpdateSQLParam(sql, new Object[] { var1 });
return true; // devuelve true y termina el metodo


En caso el valor no sea nulo, es decir, si el primer Map de la lista si tiene un valor asociado a la llave "id2", obtiene el "id2" en milisegundos (al parecer es una fecha) y la fecha actual también en milisegundos. Luego los compara: Si la fecha en milisegundos de hoy es mayor que id2 en milisegundos, se elimina el usuario de la tabla.

Código (=java) [Seleccionar]

Calendar cal = Calendar.getInstance();
// Fecha ID2 (avanzada) en milisegundos en la base de datos
Long var1 = Long.valueOf(Long.parseLong("" + id2));
// Fecha actual en milisegundos
Long var2 = Long.valueOf(cal.getTime().getTime());
// si la actual es mayor que la avanzada: FIN DE LICENCIA!
if (var2.longValue() > var1.longValue()) {
sql = "DELETE FROM TB_CIV_TMP"; // elimina al user de la DB
executeUpdateSQL(sql); // ejecuta la sentencia sql
return false; // fin del metodo y devuelve false
}


De lo anterior podemos resumir que:

Hace una consulta a la base de datos para obtener los campos ID1 e ID2 que al parecer son un fechas, de acuerdo a un valor para ID1.

Calculamos la fecha en milisegundos que está en la base de datos (id2) con la fecha en milisegundos actual. Si la actual es mayor, se elimina el usuario de la base de datos.

Si ID2 no tiene un campo establecido en la base de datos, se obtiene la fecha 80 días en adelante en milisegundos y se guarda en la base de datos.


Conclusión:

Al parecer éste algoritmo trata sobre verificación de licencias de usuario de algún software.


PD: Creo que no es necesario que te diga dónde tienes que manejar las fechas (ya lo he explicado en el análisis). Salu2.

taos19

Cita de: Mitsu en 21 Marzo 2014, 07:23 AM
Hola, vamos a hacer un análisis de este algoritmo que a simple vista no entiendo nada xD

Esta línea obtiene los campos ID1, ID2 de la tabla TB_CIV_TEMP cuando el ID1 es desconocido, es decir luego se seteará el parámetro de condición.
Código (=java) [Seleccionar]

String sql = "SELECT ID1, ID2 FROM TB_CIV_TMP WHERE ID1 = ?";


Luego hace uso de un método del cual no podemos ver nada pero al parecer devuelve fechas en milisegundos (para poder compararse luego). Este método recibe 3 parámetros: La query, un array String y un array Object.

Dado que no puedo ver el código de éste método, creo que no hace falta decirte que no entiendo ni un carajo para qué sirve xD

Código (=java) [Seleccionar]

List<Map> obj = findMapBySQLParam(sql, new String[] { "id1", "id2" }, new Object[] { "202cb962ac59075b964b07152d234b70" });


Ahora, podemos deducir que el método findMapBySQLParam() concatenerá algún valor (alguna fecha en milisegundos quizás) con la query y hará la consulta. Por otro lado, si no se puede realizar la consulta o no hay coincidencias con la consulta, la lista puede ser nula (si no se ha podido realizar la consulta) o vacía (si no hay coincidencias). Si ésto llegara a pasar, devuelve false y termina el método.

Crea un objeto Object y le asigna el valor de la llave "id2" del primer Map de la lista recibida.

Código (=java) [Seleccionar]

// obj.get(0) -> obtiene el primer elemento de la lista. En este caso el primer Map
// .get("id2") -> obtiene el valor asociado a la llave "id2"
Object id2 = (Map) obj.get(0).get("id2");


Si el valor es nulo, es decir no hay una llave con ese identificador lo crea:

Código (=java) [Seleccionar]

Calendar cal = Calendar.getInstance(); // obtiene una instancia Calendar
// el primer parametro debe ser una constante. 5 equivale a Calendar.DAY
// el segundo parametro le suma 80 al tipo de dato de la constante. Ej.,
// si es Calendar.DAY y hoy estamos 20, adelanta la fecha en 80 dias.
call.add(5,80);
// Obtiene la fecha avanzada en milisegundos
Long var1 = Long.valueOf(cal.getTime().getTime());
// actualiza el campo ID2 con la fecha avanzada en milisegundos (al parecer)
sql = "UPDATE TB_CIV_TMP SET ID2 = ?";
executeUpdateSQLParam(sql, new Object[] { var1 });
return true; // devuelve true y termina el metodo


En caso el valor no sea nulo, es decir, si el primer Map de la lista si tiene un valor asociado a la llave "id2", obtiene el "id2" en milisegundos (al parecer es una fecha) y la fecha actual también en milisegundos. Luego los compara: Si la fecha en milisegundos de hoy es mayor que id2 en milisegundos, se elimina el usuario de la tabla.

Código (=java) [Seleccionar]

Calendar cal = Calendar.getInstance();
// Fecha ID2 (avanzada) en milisegundos en la base de datos
Long var1 = Long.valueOf(Long.parseLong("" + id2));
// Fecha actual en milisegundos
Long var2 = Long.valueOf(cal.getTime().getTime());
// si la actual es mayor que la avanzada: FIN DE LICENCIA!
if (var2.longValue() > var1.longValue()) {
sql = "DELETE FROM TB_CIV_TMP"; // elimina al user de la DB
executeUpdateSQL(sql); // ejecuta la sentencia sql
return false; // fin del metodo y devuelve false
}


De lo anterior podemos resumir que:

Hace una consulta a la base de datos para obtener los campos ID1 e ID2 que al parecer son un fechas, de acuerdo a un valor para ID1.

Calculamos la fecha en milisegundos que está en la base de datos (id2) con la fecha en milisegundos actual. Si la actual es mayor, se elimina el usuario de la base de datos.

Si ID2 no tiene un campo establecido en la base de datos, se obtiene la fecha 80 días en adelante en milisegundos y se guarda en la base de datos.


Conclusión:

Al parecer éste algoritmo trata sobre verificación de licencias de usuario de algún software.


PD: Creo que no es necesario que te diga dónde tienes que manejar las fechas (ya lo he explicado en el análisis). Salu2.

Impresionante respuesta. Muchas gracias por el tiempo y la explicacion.

Otra pregunta... quisiera saber como seria la forma de verificar con otra fecha almacenada en otra base de datos y ahi si evitar el ingreso del usuario despues de 15 dias por ejemplo

Mitsu

#3
Muchas gracias y ante cualquier duda, ya sabes que tienes que elegir ElHacker ;)

Respecto a tu pregunta, yo haría lo siguiente:

  • Asociar las fechas a un ID_USUARIO que será la PK.

    Así sería muy fácil. Primero obtenemos los registros por el ID_USUARIO. Una vez que tengamos los registros (las fechas) podremos trabajar fácilmente.

    Sería algo así, aclaro que no lo he probado y quizás debe tener algunos errores, de eso ya te encargas tú. Espero hayas aprendido a cómo realizarlo.

    Código (=java) [Seleccionar]

    public boolean validarLicencia(long id) throws SQLException {
          try {
    String sentencia = "SELECT ID1, ID2 FROM TUTABLA WHERE ID_USUARIO = ?";
    Map mapaUsuario = obtenerMapaPorUserID(sentencia, id);

    Long id2 = (Long) mapaUsuario.get(0).get("id2"); // obtiene el valor asociado a la llave 'id2' del Map 'mapaUsuario'

    if(mapaUsuario = null && mapaUsuario.size() == 0) { return false; }

    if (id2 == null)  { // si el campo id2 es null en la tabla
    Calendar calendario = Calendar.getInstance();
    calendario.add(5,15) // la fecha de vencimiento es en 15 dias
    Long fechaHoyMiliseg = cal.getTime().getTime(); // obtiene fecha en milisegunos
    String sentencia = "UPDATE TUTABLA SET ID2 = ?";
    ejecutarSentenciaPorUserId(sentencia, fechaHoyMiliseg);
    return true; // informa que la licencia es valida
    }

    // Si existe el campo ID2
    Calendar calendario = Calendar.getInstance();
    Long fechaLimiteMiliseg = id2; // le asigna el valor de id2 recuperado del usuario
    Long fechaHoyMiliseg = calendario.getTime().getTime();
    if (fechaHoyMiliseg > fechaMiliteMiliseg) { // YA SE VENCIO LICENCIA!
    String sentencia = "DELE FROM TUTABLA WHERE ID_USUARIO = ?";
    ejecutarSentenciaPorUserId(sentencia, id);
    return false; // informa que la licencia ya vencio
    }
           } catch (SQLException ex) { throw ex; }
         finally { /* cierras flujos*/ }

         return true; // solo para que no de error ya que se debe de colocar el retorno
    }


    Método que obtiene un Map por id de usuario:
    Código (=java) [Seleccionar]

    public Map obtenerMapaPorUserID(String sql, id) throws SQLException {
           try {
    // obtienes tu conexion y declaras previamente un preparedStatement
    estatuto = conexion.preparedStatement(sql);
    estatuto.setLong(1,user); // asigna el id a la consulta
    ResultSet rs = estatuto.executeQuery();
    Map<String llave, Long valor) mapaUsuario = new HashMap<>();
    while(rs.next()) {
    mapaUsuario.put("id1",rs.getLong("ID1"));
    mapaUsuario.put("id2",rs.getLong("ID2"));
    }
          } catch (SQLException ex) { throw ex; }
          finally { /* cierras flujos*/ }
    return mapaUsuario; // en caso no haya coincidencias devolvera una lista vacia (mapaUsuario.size() == 0)
    }


    Método que ejecuta una sentencia por id de usuario:

    Código (=java) [Seleccionar]

    public void ejecutarSentenciaPorUserId(String sentencia, long id) throws SQLException {
            try {
           // obtienes tu conexion y haces un executeUpdate();
            } catch (SQLException ex) { throw ex; }
            finally { /* cierras flujos*/ }
    }

taos19

Cita de: Mitsu en 21 Marzo 2014, 14:20 PM
Muchas gracias y ante cualquier duda, ya sabes que tienes que elegir ElHacker ;)

Respecto a tu pregunta, yo haría lo siguiente:

  • Asociar las fechas a un ID_USUARIO que será la PK.

    Así sería muy fácil. Primero obtenemos los registros por el ID_USUARIO. Una vez que tengamos los registros (las fechas) podremos trabajar fácilmente.

    Sería algo así, aclaro que no lo he probado y quizás debe tener algunos errores, de eso ya te encargas tú. Espero hayas aprendido a cómo realizarlo.

    Código (=java) [Seleccionar]

    public boolean validarLicencia(long id) throws SQLException {
          try {
    String sentencia = "SELECT ID1, ID2 FROM TUTABLA WHERE ID_USUARIO = ?";
    Map mapaUsuario = obtenerMapaPorUserID(sentencia, id);
          } catch (SQLException ex) { throw ex; }
          finally { /* cierras flujos*/ }

    Long id2 = (Long) mapaUsuario.get(0).get("id2"); // obtiene el valor asociado a la llave 'id2' del Map 'mapaUsuario'

    if(mapaUsuario = null && mapaUsuario.size() == 0) { return false; }

    if (id2 == null)  { // si el campo id2 es null en la tabla
    Calendar calendario = Calendar.getInstance();
    calendario.add(5,15) // la fecha de vencimiento es en 15 dias
    Long fechaHoyMiliseg = cal.getTime().getTime(); // obtiene fecha en milisegunos
    String sentencia = "UPDATE TUTABLA SET ID2 = ?";
    ejecutarSentenciaPorUserId(sentencia, fechaHoyMiliseg);
    return true; // informa que la licencia es valida
    }

    // Si existe el campo ID2
    Calendar calendario = Calendar.getInstance();
    Long fechaLimiteMiliseg = id2; // le asigna el valor de id2 recuperado del usuario
    Long fechaHoyMiliseg = calendario.getTime().getTime();
    if (fechaHoyMiliseg > fechaMiliteMiliseg) { // YA SE VENCIO LICENCIA!
    String sentencia = "DELE FROM TUTABLA WHERE ID_USUARIO = ?";
    ejecutarSentenciaPorUserId(sentencia, id);
    return false; // informa que la licencia ya vencio
    }

    return true; // solo para que no de error ya que se debe de colocar el retorno
    }


    Método que obtiene un Map por id de usuario:
    Código (=java) [Seleccionar]

    public Map obtenerMapaPorUserID(String sql, id) throws SQLException {
           try {
    // obtienes tu conexion y declaras previamente un preparedStatement
    estatuto = conexion.preparedStatement(sql);
    estatuto.setLong(1,user); // asigna el id a la consulta
    ResultSet rs = estatuto.executeQuery();
    Map<String llave, Long valor) mapaUsuario = new HashMap<>();
    while(rs.next()) {
    mapaUsuario.put("id1",rs.getLong("ID1"));
    mapaUsuario.put("id2",rs.getLong("ID2"));
    }
          } catch (SQLException ex) { throw ex; }
          finally { /* cierras flujos*/ }
    return mapaUsuario; // en caso no haya coincidencias devolvera una lista vacia (mapaUsuario.size() == 0)
    }


    Método que ejecuta una sentencia por id de usuario:

    Código (=java) [Seleccionar]

    public void ejecutarSentenciaPorUserId(String sentencia, long id) throws SQLException {
            try {
           // obtienes tu conexion y haces un executeUpdate();
            } catch (SQLException ex) { throw ex; }
            finally { /* cierras flujos*/ }
    }

Estoy muy agradecido mitsu.  Voy a implementarlo y te cuento