Herramientas Informaticas

Categoría: Uncategorized Página 7 de 13

Respaldos Automáticos y Eficientes de Bases de Datos MySQL con mysql-backup

La protección de los datos de una aplicación es fundamental. Los respaldos de bases de datos son una línea de defensa esencial ante posibles pérdidas de información causadas por errores humanos, fallas del sistema o ciberataques. En este post, te presentaremos una solución práctica y flexible para realizar respaldos automáticos de bases de datos MySQL: la herramienta mysql-backup autor original ramazancetinkaya/mysql-backup y las modificaciones que hemos implementado en nuestro fork julio101290.

¿Por qué un fork de mysql-backup?

Partiendo de la excelente base que ofrece mysql-backup, decidimos crear un fork con el objetivo de adaptar la herramienta a nuestras necesidades específicas y resolver ciertas limitaciones que identificamos durante su uso. Algunos de los motivos que nos llevaron a crear este fork fueron:

  • Mejorar el rendimiento: Optimizamos el proceso de respaldo, especialmente para bases de datos de gran tamaño, dividiendo las consultas en fragmentos más pequeños y evitando operaciones innecesarias.
  • Aumentar la estabilidad: Identificamos y corregimos algunos errores que podían causar inestabilidad en ciertos escenarios, como el manejo de valores nulos o la separación de consultas.
  • Añadir funcionalidades: Incorporamos nuevas características para ampliar las capacidades de la herramienta, como la posibilidad de personalizar el formato de los archivos de respaldo o integrar la herramienta con otros sistemas.

Instalación con Composer

Para instalar nuestro fork de mysql-backup, utiliza el siguiente comando en tu terminal:

Bash

composer require julio101290/mysql-backup

Usa el código con precaución.

Personalizaciones Realizadas

Hemos realizado las siguientes personalizaciones en nuestro fork:

  • División de consultas: Para mejorar el rendimiento en bases de datos grandes y evitar errores de conexión.
  • Simplificación de transacciones: Eliminamos el uso de transacciones innecesarias para reducir la complejidad.
  • Manejo de valores nulos: Aseguramos una representación correcta de los valores nulos en los respaldos.
  • Mejora del separador de consultas: Utilizamos un separador más robusto para evitar errores en la restauración.

Ejemplo de Uso con CodeIgniter4

PHP

// ... (código existente)

// Cargar la clase MySQLBackup
use Julio101290/MysqlBackup\Backup;

// ... (resto del código)

Usa el código con precaución.

Conclusión

Nuestro fork de mysql-backup ofrece una solución robusta y eficiente para realizar respaldos automáticos de bases de datos MySQL. Al personalizar esta herramienta, hemos obtenido un mayor control y flexibilidad para adaptarla a nuestras necesidades específicas.

Recomendaciones Adicionales:

  • Automatización: Integra esta funcionalidad en un sistema de automatización para realizar respaldos de forma periódica.
  • Seguridad: Implementa medidas de seguridad adecuadas para proteger los archivos de respaldo.
  • Pruebas: Realiza pruebas periódicas de restauración para verificar la integridad de los respaldos.
  • Documentación: Consulta la documentación completa de nuestro fork en GitHub para obtener más información.

Ejemplo de Uso con CodeIgniter4

PHP

// ... (código existente)

// Cargar la clase MySQLBackup
use Julio101290\MysqlBackup\Backup;

// Obtener los datos de conexión a la base de datos
$host = config('Database')->default["hostname"];
$dbname = config('Database')->default["database"];
$username = config('Database')->default["username"];
$password = config('Database')->default["password"];
$port = config('Database')->default["port"];

$DNS = "mysql:host=$host;port:$port;dbname=$dbname'";

$dbBackupConection = new \PDO($DNS, $username, $password);

// Crear una instancia de MySQLBackup
$mysqlBackup = new MySQLBackup($dbBackupConection, ROOTPATH . "writable/database/backup");

// Realizar un respaldo completo
$backup = $mysqlBackup->backup(false, true, false);

// ... (resto del código)

Usa el código con precaución.

Restauración de un Respaldo

PHP

// ... (código existente)

// Restaurar un respaldo
$restore = $mysqlBackup->restore($infoBackups["SQLFile"], true);

// ... (resto del código)

Usa el código con precaución.

Instalador Completo: Inno Setup + MariaDB 11.5

Entrada fija

Subscribe to continue reading

Subscribe to get access to the rest of this post and other subscriber-only content.

Sistema de planeación proyectos y costos

Al momento de realizar cualquier proyecto, ya sea desarrollo de software, construcción , administración de servicios de taller de automóviles, o actividades del día a día es necesario saber administrarnos y desde antes tener el estimado de las horas e insumos que vamos a consumir en las tareas a realizarse.

También es necesario verificar a través de los  diferentes reportes el avance de las actividades del proyecto, así como quien es el responsable de cada actividad.

Posteriormente podremos ver el rendimiento por empleado y ver las horas trabajadas en un periodo de tiempo seleccionado

Con este sistema podremos crear un proyecto, separarlo por etapas, conceptos y actividades, asignarle a la actividad a un empleado, un tiempo o cantidad estimada y conforme se avanza en la actividad se va registrando el tiempo o la cantidad real, se le asigna costo ligando a un producto.

Una vez registrada las actividades podemos imprimir en PDF un presupuesto en la que nos muestra primeramente un resumen del costo por etapa en la primera hoja y en las siguientes nos mostrará todo el proyecto desglosado

También tenemos una tabla dinámica para poder leer la información y organizarla de manera que más cómoda al lector, por ejemplo, en la siguiente imagen vemos el avance por proyecto separado por concepto

Leer consultas Personalizadas en Service Layer SAP

Ahora lo importante, como ejecutar la consulta personalizada para leer la información

Hacer la siguiente petición y entre paréntesis ponemos el código de la consulta

https://localhost:50000/b1s/v1/SQLQueries('sql02')/List

En el body ponemos el JSON con los parámetros

{
 "ParamList": "listaPrecios=6"
}

Quedando de la siguiente forma

Modificar consultas Personalizadas en Service Layer SAP

Como no todo queda a la primera o se tenga que modificar por cualquier razón la consulta personalizada, les dejo el ejemplo básico de como modificar una consulta personalizada

Para modificar la consulta creada anteriormente hacemos la siguiente petición de tipo PATH

https://localhost:50000/b1s/v1/SQLQueries('sql02')

En el body metemos el JSON ya modificado

{
  "SqlCode":"sql02",
  "SqlName":"listPrices",
  "SqlText":"select a.ItemCode
                   ,a.PriceList
                   ,a.Price 
                   ,b.ListName
                   ,z.[ItemName]
            from [ITM1] a
                , [OPLN]	b
                , [OITM] z
            where a.[PriceList] =:listaPrecios
            and a.[Price] <>0
            AND a.[PriceList]  = b.[ListNum]
            AND a.[ItemCode]  = z.[ItemCode]
  ",
  "ParamList" : "listaPrecios"

}

Quedaría de la siguiente forma

Crear Consultas Personalizadas en Service Layer SAP

En el service layer también tenemos la forma para crear nuestras consultas personalizadas, aunque tiene algunas limitaciones pero nos pueden ser muy útiles.

Para ello utilizaremos SQLQueries y el ejemplo básico seria de la siguiente manera

Hacemos la petición POST

https://localhost:50000/b1s/v1/SQLQueries

En el body le metemos el contenido JSON

{
  
  "SqlCode":"sql02",
  "SqlName":"listPrices",
  "SqlText":"select ItemCode,PriceList 
            from [ITM1]  
            where [PriceList] =:listaPrecios ",
  "ParamList" : "listaPrecios"
  
  
}

Al final quedaría de la siguiente forma

Obtener la lista de precios de SAP a través Service Layer

Para traer la el catalogo de listas de precios usaremos la siguiente URL en GET

https://localhost:50000/b1s/v1/PriceLists?$select=PriceListNo,PriceListName&$filter=Active eq 'tYES'  and substringof('TRIT',PriceListNo) or substringof('TRIT',PriceListName)

Como pueden observar usamos la funcion substringof como el equivalente al like de SQL

Quedaría mas o menos de esta forma

Ahora la función quedaría de la siguiente forma

    /* =============================================
      MOSTRAR
      ============================================= */

    static public function ctrMostrar($cookie, $filtro) {


        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_PORT => "50000",
            CURLOPT_URL => "https://localhost:50000/b1s/v1/PriceLists?%24select=PriceListNo%2CPriceListName&%24filter=Active%20eq%20'tYES'%20%20and%20substringof('$filtro'%2CPriceListNo)%20or%20substringof('$filtro'%2CPriceListName)",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_COOKIE => $cookie,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_HTTPHEADER => [
                "Accept: */*",
                "User-Agent: Thunder Client (https://www.thunderclient.com)"
            ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
            return "cURL Error #:" . $err;
        } else {
            return json_decode($response);
        }


        $response = json_decode($response);

        return $response;
    }

Y bien saben el resto es historia

Obtener lista de usuarios SAP a través de Service Layer

Lo que haremos en esta ocasión en hacer la consulta al service layer para usarlo en un Select2 vía AJAX y PHP primera mente usaremos la siguiente petición de tipo GET URL

https://localhost:50000/b1s/v1/Users?$select=InternalKey,UserCode,Group,UserName&$filter=Group eq 'ug_Regular'  and substringof('Julio',UserName)  or substringof('Julio',UserCode)&$orderby=InternalKey

Como ven usamos la función substringof que seria el equivalente en SQL al like ‘%%’

Quedando mas o menos asi

Ahora transformamos la petición a una función de PHP en la que recibimos la cookie y el filtro para buscar los usuarios

    /* =============================================
      MOSTRAR
      ============================================= */

    static public function ctrMostrar($cookie, $filtro) {


        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_PORT => "50000",
            CURLOPT_URL => "https://localhost:50000/b1s/v1/Users?%24select=InternalKey%2CUserCode%2CGroup%2CUserName&%24filter=Group%20eq%20'ug_Regular'%20%20and%20substringof('$filtro'%2CUserName)%20%20or%20substringof('$filtro'%2CUserCode)&%24orderby=InternalKey",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_COOKIE => $cookie,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_HTTPHEADER => [
                "Accept: */*",
                "User-Agent: Thunder Client (https://www.thunderclient.com)"
            ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
            return "cURL Error #:" . $err;
        } else {
            return json_decode($response);
        }


        $response = json_decode($response);

        return $response;
    }

Ahora en el archivo de consulta se usaría de la siguiente forma, hacemos el Login, consultamos, hacemos el Logout, y formamos la cadena JSON de la siguiente forma

   $busqueda = $_POST["searchTerm"];

    $conexionSAP = ServiceLayer::login();

    $cookie = "B1SESSION=" . $conexionSAP->SessionId . ";  ROUTEID=.node1";

    $usuariosSAP = ControladorUsuariosSAP::ctrMostrar($cookie, $busqueda);

    $usuariosSAPLista = $usuariosSAP->value;

    $usuariosSAP = ServiceLayer::logout($cookie);

    $jsonVariable = ' { "results": [';

    foreach ($usuariosSAPLista as $keyUsuarios1 => $valueUsuarios1) {


        $jsonVariable .= ' {
      "id": "' . $valueUsuarios1->UserCode . '",
      "text": "' . utf8_encode($valueUsuarios1->UserCode . " - " . $valueUsuarios1->UserName) . '"
    },';
    }

    $jsonVariable = substr($jsonVariable, 0, -1);

    $jsonVariable .= ' ]
}';

    echo ($jsonVariable);

Y listo ya esto obtenemos los datos requeridos

Haciendo Logout en Service Layer en SAP y pasar el código en PHP 8.3

Bien ahora vamos a mostrar como hacer el logout, es decir, cerrar la sesión, vamos hacer la petición tipo GET con la siguiente URL

https://localhost:50000/b1s/v1/Logout

Quedando de la siguiente forma

La función en PHP seria la siguiente

 static public function logout($cookie) {

        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_PORT => "50000",
            CURLOPT_URL => "https://hanagusa:50000/b1s/v1/Logout",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_COOKIE => $cookie,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_HTTPHEADER => [
                "Accept: */*",
                "User-Agent: Gisa Web Client (https://www.thunderclient.com)"
            ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
            return "cURL Error #:" . $err;
        } else {
            return $response;
        }
    }

Ya al momento de usarlo en PHP desde el Login has ta el Logout seria de la siguiente forma

$conexionSAP = ServiceLayer::login();

// Construimos la cookie

$cookie = "B1SESSION=" . $conexionSAP->SessionId . ";  ROUTEID=.node1";

$sucursalesSAP = ControladorSucursalSAP::ctrMostrar($cookie);

$sucursalesSAP = $sucursalesSAP->value;

// Cerramos la session enviando la Cookie
$conexionSAP = ServiceLayer::logout($cookie);

Ejemplos Service Layer SAP

A continuación pondremos a su disposición algunos ejemplos de peticiones al Service Layer del SAP así como el código en PHP

  1. Postman en Visual Studio Code
  2. Haciendo Login en Service Layer en SAP y pasar el código en PHP 8.3
  3. Haciendo Logout en Service Layer en SAP y pasar el código en PHP 8.3
  4. Obtener lista de usuarios SAP a través de Service Layer
  5. Obtener la lista de precios de SAP a través Service Layer
  6. Crear Consultas Personalizadas en Service Layer SAP
  7. Modificar consultas Personalizadas en Service Layer SAP
  8. Leer consultas Personalizadas en Service Layer SAP

Página 7 de 13

Creado con WordPress & Tema de Anders Norén