One place for hosting & domains

      Ubuntu

      Cómo crear un paquete y publicar una aplicación de Snap en Ubuntu 18.04


      El autor seleccionó la Electronic Frontier Foundation para recibir una donación como parte del programa Write for DOnations.

      Introducción

      Uno de los mayores desafíos en el desarrollo de aplicaciones es el paso final de distribuir el producto acabado a sus usuarios o clientes. Muchos de los métodos para la implementación de aplicaciones carecen de sencillez y seguridad o no incorporan estrategias para actualizar de forma automática una aplicación una vez que se instaló.

      Snap es un formato moderno de empaquetamiento de aplicaciones que cuenta con potentes funciones de banco de pruebas y seguridad e incluye aislamiento del sistema de archivos, actualizaciones automáticas y gestión de dependencias integrada. Las aplicaciones Snap, conocidas como Snaps, pueden descargarse e instalarse usando un programa de línea de comandos, similar a apt o yum. Ubuntu viene con Snap previamente instalado, lo cual significa que las aplicaciones Snap tienen muchos adeptos.

      A través de este tutorial, creará una aplicación Snap y la publicará en la Snap Store.

      Requisitos previos

      Para completar este tutorial, necesitará lo siguiente:

      • Un servidor de Ubuntu 18.04 configurado conforme a la Configuración inicial de servidores con Ubuntu 18.04, con un usuario sudo no root.

      • Una aplicación que quiere empaquetar y publicar en el formato Snap. Esta puede ser una aplicación compleja que creó, un proyecto común de código abierto, o un simple “¡Hello, world!”. Mundo!”. Si aún no tiene una aplicación, en el paso 1 de este tutorial se abordará la manera de crear un programa Hello World en Go.

      • Una cuenta en el panel de control de Snapcraft para desarrolladores.

      Una vez que tenga todo esto listo, inicie sesión en su servidor como usuario no root.

      Paso 1: Preparar su aplicación para agregarla a un paquete

      Primero, preparará su aplicación para empaquetarla como aplicación Snap asegurándose de que todo lo necesario esté presente en un único directorio.

      Comience creando un nuevo directorio para su Snap y posicionándose en él:

      • mkdir ~/your-snap
      • cd ~/your-snap

      A continuación, si ya dispone de una aplicación, disponga una copia completa del código fuente de su aplicación en el directorio que acaba de crear. El proceso aquí variará considerablemente según la aplicación exacta que empaquete; sin embargo, en caso de que el código fuente se almacene en un repositorio de Git, puede aplicar git init en un repositorio del directorio y extraer todo el código pertinente.

      Si aún no tiene una aplicación que desee empaquetar, puede crear un programa “Hello World” para usarlo como alternativa. Si desea más información sobre cómo escribir este programa con Go, consulte el tutorial Cómo escribir su primer programa en Go.

      Puede hacer esto creando primero un nuevo archivo de Go y abriéndolo con su editor de texto preferido:

      A continuación, añada el siguiente código al archivo:

      helloworld.go

      package main
      import "fmt"
      func main() {
        fmt.Println("Hello, world!")
      }
      

      Guarde el archivo y ciérrelo.

      Si no tiene Go instalado, puede instalarlo usando el siguiente comando:

      • sudo apt install golang-go

      Una vez instalado Go, puede ejecutar su nuevo programa para comprobar que funcione:

      Verá el siguiente resultado:

      Output

      Hello, world!

      Con esto, habrá preparado su aplicación para empaquetarla con el formato Snap. A continuación, instalará el software necesario para iniciar el proceso de empaquetamiento.

      Paso 2: Instalar Snapcraft

      En este paso, descargará e instalará Snapcraft; este es el nombre que recibe la herramienta oficial de creación de paquetes de aplicaciones Snap. Snapcraft está disponible en la Snap Store, que existe en Ubuntu por defecto. Esto significa que puede instalar Snapcraft desde la línea de comandos usando el comando snap.

      El comando snap es equivalente al comando apt, pero puede usarlo para instalar software desde la Snap Store, en lugar de paquetes desde los repositorios Apt.

      Para instalar Snapcraft, ejecute el siguiente comando:

      • sudo snap install snapcraft --classic

      Se utiliza el argumento de comando --classic para que Snapcraft se instalae sin las funciones de banco de pruebas estrictas que normalmente se usan en las Snaps. Snapcraft requiere este argumento, ya que necesita más acceso privilegiado a su sistema para empaquetar las aplicaciones de forma fiable.

      Una vez que instale Snapcraft, verá lo siguiente:

      Output

      snapcraft 3.9.8 from Canonical✓ installed

      Finalmente, puede verificar la instalación de Snapcraft ejecutando lo siguiente:

      Con esto se mostrará algo similar a lo siguiente:

      Output

      snapcraft, version 3.9.8

      Ahora que instaló Snapcraft, puede empezar a definir la configuración y los metadatos para su aplicación Snap.

      En este paso, empezará a definir la configuración, la estructura y los metadatos para su aplicación Snap.

      Comience verificando que aún esté trabajando en el directorio de su aplicación Snap:

      A continuación, cree y edite el archivo snapcraft.yaml usando su editor de texto preferido:

      Usará el archivo snapcraft.yaml para almacenar toda la configuración para su aplicación Snap, incluidos el nombre, la descripción y la versión, además de los ajustes relacionados con la gestión de dependencias y el banco de pruebas.

      Comience definiendo el nombre, el resumen, la descripción y el número de la versión de su aplicación:

      snapcraft.yaml

      name: your-snap
      summary: A summary of your application in 78 characters or less.
      description: |
        A detailed description of your application.
        The description can have multiple lines.
      version: '1.0'
      

      El nombre de su Snap debe ser único si desea publicarla en la Snap Store; busque otras aplicaciones con el mismo nombre para asegurarse de que no exista aún.

      A continuación, puede definir el comando o los comandos que desee asociar a su aplicación. Esto permitirá usar su Snap desde la línea de comandos Bash como un comando normal.

      Agregue lo siguiente a su archivo snapcraft.yaml:

      snapcraft.yaml

      . . .
      apps:
        your-snap-command:
          command: your-snap
      

      your-snap-command es el nombre del comando que desea definir. Por ejemplo, es posible que desee usar el comando helloworld para ejecutar su programa Hello World.

      Se utiliza el comando: your-snap para indicar a Snapcraft lo que debe hacer cuando se ejecuta el comando de la aplicación. En el caso del programa Hello World, usaría el valor helloworld para hacer referencia al archivo helloworld.go, lo que permitirá a Snapcraft ejecutar su programa de forma correcta.

      Como resultado, se obtiene la siguiente configuración de ejemplo:

      snapcraft.yaml

      apps:
        helloworld:
          command: helloworld
      

      Si el nombre del comando coincide exactamente con el nombre de la Snap, podrá ejecutarlo de manera directa desde la línea de comandos. Si el comando no coincide con el nombre de la Snap, se le añadirá automáticamente el nombre de la Snap. Por ejemplo, helloworld.command1.

      Por último, puede definir las partes que formarán su aplicación Snap. Las aplicaciones Snap constan de varias partes, que son todos los componentes que forman su aplicación. En muchos casos solo hay una parte, que es la aplicación en sí misma.

      Cada parte tiene un complemento asociado. Por ejemplo, para los componentes de su aplicación escritos en Ruby se utiliza el complemento ruby y para los componentes escritos en Go se utiliza el complemento go.

      Puede usar el comando list-plugins de Snapcraft a fin de identificar los complementos correctos para su aplicación.

      Con esto, se mostrará algo similar a lo siguiente:

      Output

      ant catkin-tools conda dump gradle make nil python rust autotools cmake crystal go kbuild maven nodejs qmake scons catkin colcon dotnet godeps kernel meson plainbox-provider ruby waf

      Los complementos más comunes son aquellos para los lenguajes de programación más habituales, como Go, Rust, Ruby o Python.

      Una vez que haya identificado los complementos correctos para su aplicación, podrá comenzar a añadir la configuración parts a su archivo snapcraft.yaml:

      snapcraft.yaml

      . . .
      parts:
        your-snap:
          plugin: plugin-name
          source: .
      

      Se utiliza el parámetro de configuración source para especificar la ruta relativa del código fuente de su aplicación. Normalmente, este será el mismo directorio que el del archivo snapcraft.yaml, de modo que el valor source es un punto (.).

      Nota: Si en el componente de su aplicación hay dependencias que se necesiten para su compilación o ejecución, puede especificarlas usando los atributos build-packages y stage-packages. Los nombres de dependencias especificados se obtendrán automáticamente a través del administrador de paquetes predeterminado de su sistema.

      Por ejemplo:

      snapcraft.yaml

      parts:
        your-snap:
        plugin: plugin-name
        source: .
        build-packages:
        - gcc
        - make
        stage-packages:
        - libcurl4
      

      Algunos complementos de Snapcraft tienen sus propias opciones específicas que pueden ser necesarias para su aplicación, de modo que vale la pena revisar las páginas pertinentes del manual para su complemento:

      • snapcraft help plugin-name

      En el caso de las aplicaciones de Go, especificaría también el go-importpath. Para la configuración de Hello World, como resultado de esto se obtiene la siguiente configuración de ejemplo:

      snapcraft.yaml

      parts:
        helloworld:
          plugin: go
          source: .
          go-importpath: helloworld
      

      Puede dejar su archivo snapcraft.yaml abierto para añadir ajustes en el siguiente paso.

      Con esto, definió la configuración básica para su aplicación Snap. A continuación, configurará los aspectos de seguridad y banco de pruebas de su aplicación.

      Paso 4: Proteger su aplicación Snap

      Las aplicaciones Snap están diseñadas para ejecutarse en un entorno de banco de pruebas. Por ello, en este paso configurará el banco de pruebas para su Snap. Primero, deberá habilitar el banco de pruebas para su aplicación, conocido en Snapcraft como confinement.

      Agregue lo siguiente a su archivo snapcraft.yaml:

      snapcraft.yaml

      . . .
      confinement: strict
      

      Esto permitirá la aplicación de un banco de pruebas para su aplicación, lo cual evitará que esta acceda a Internet, a otras Snaps en ejecución o al sistema host. Sin embargo, en la mayoría de los casos, no es necesario que las aplicaciones puedan comunicarse fuera de su banco de pruebas, como cuando necesitan acceder a Internet o realizar tareas de lectura y escritura en el sistema de archivos.

      Estos permisos, conocidos en Snapcraft como interfaces, pueden concederse a su aplicación Snap mediante Plugs. Usando los Plugs, puede controlar de forma exhaustiva el banco de pruebas de su aplicación para darle el acceso que requiere y nada más (principio de privilegio menor).

      Las interfaces exactas necesarias variarán dependiendo de su aplicación. Las siguientes son algunas de las interfaces más comunes:

      • audio-playback: permite la salida de audio y la reproducción de sonidos.
      • audio-record: permite la entrada y grabación de audio.
      • camera: permite el acceso a cámaras web conectadas.
      • home: permite el acceso a archivos no ocultos en su directorio de inicio.
      • network: permite el acceso a la red y a Internet.
      • network-bind: permite la vinculación a puertos para el funcionamiento como servicio de red.
      • system-files: permite el acceso a todo el sistema de archivos del equipo host.

      La lista completa de interfaces disponibles está en la documentación de Snapcraft, en la sección Supported Interfaces (interfaces compatibles).

      Una vez que haya identificado todas las interfaces requeridas para su aplicación, puede comenzar a asignarlas a los plugs en su archivo snapcraft-yaml.

      La siguiente configuración de ejemplo permitirá que la aplicación acceda a la red y al área de inicio de los usuarios:

      snapcraft.yaml

      . . .
      plugs:
        your-snap-home:
          interface: home
        your-snap-network:
          interface: network
      

      Guarde y cierre su archivo.

      El nombre del Plug debería ser descriptivo para ayudar a los usuarios a identificar su finalidad.

      Habilitó el banco de pruebas para su Snap y configuró algunos Plugs para conceder acceso limitado a recursos del sistema. A continuación, terminará de compilar su aplicación Snap.

      Paso 5: Compilar y probar su aplicación Snap

      Ahora que escribió toda la configuración necesaria para su Snap, puede proceder con la compilación y prueba del paquete de Snap a nivel local.

      Si ha seguido los pasos de este tutorial con un programa Hello World como aplicación, su archivo snapcraft.yaml completo ahora tendrá un aspecto similar al siguiente:

      snapcraft.yaml

      name: helloworld
      summary: A simple Hello World program.
      description: |
        A simple Hello World program written in Go.
        Packaged as a Snap application using Snapcraft.
      version: '1.0'
      confinement: strict
      
      apps:
        helloworld:
          command: helloworld
      
      parts:
        helloworld:
          plugin: go
          source: .
          go-importpath: helloworld
      
      plugs:
        helloworld-home:
          interface: home
        helloworld-network:
          interface: network
      

      Para compilar su aplicación Snap, ejecute el comando snapcraft desde el directorio de esta:

      Snapcraft iniciará automáticamente una máquina virtual (VM) y comenzará a compilar su Snap. Una vez completado el proceso, Snapcraft se cerrará y verá algo similar a lo siguiente:

      Output

      Snapped your-snap_1.0_amd64.snap

      Ahora puede instalar su Snap localmente para comprobar si funciona:

      • sudo snap install your-snap.snap --dangerous

      El argumento del comando --dangerous es necesario ya que se instala un Snap local sin firma.

      Output

      your-snap 1.0 installed

      Una vez completado el proceso de instalación, puede ejecutar su Snap usando su comando asociado. Por ejemplo:

      En el caso del programa Hello World de ejemplo, el resultado será el siguiente:

      Output

      Hello, world!

      También puede ver la política de banco de pruebas para su Snap, a fin de garantizar que los permisos asignados se hayan concedido de forma adecuada:

      • snap connections your-snap

      Esto dará como resultado una lista de Plugs e interfaces similar a la siguiente:

      Output

      snap connections your-snap Interface Plug Slot Notes home your-snap:your-snap-home :home - network your-snap:your-snap-network :network -

      En este paso, compiló su Snap y lo instaló localmente para probar que funciona. A continuación, publicará su Snap en la Snap Store.

      Paso 6: Publicar su Snap

      Ahora que compiló y probó su aplicación Snap, es el momento de publicarla en la Snap Store.

      Comience iniciando sesión en su cuenta de desarrollador de Snap usando la aplicación de línea de comandos de Snapcraft:

      Siga las instrucciones para introducir su dirección de correo electrónico y su contraseña.

      A continuación, deberá registrar el nombre de la aplicación en la Snap Store:

      • snapcraft register your-snap

      Una vez que registre el nombre de la Snap, podrá subir el paquete de Snap a la tienda:

      • snapcraft push your-snap.snap

      Visualizará un resultado similar al siguiente:

      Output

      Preparing to push 'your-snap_1.0_amd64.snap'. Install the review-tools from the Snap Store for enhanced checks before uploading this snap. Pushing 'your-snap_1.0_amd64.snap' [===================================================================================================] 100% Processing...| Ready to release! Revision 1 of 'your-snap' created.

      Cada vez que suba contenido a la Snap Store, el número de revisión aumentará, comenzando por uno. Esto es útil para ayudar a identificar las diferentes compilaciones de su Snap.

      Finalmente, puede publicar su Snap:

      • snapcraft release your-snap revision-number channel

      Si esta es la primera vez que sube contenido a la Snap Store, el número de revisión será 1. También puede optar por realizar su publicación en los canales stable, candidate, beta y edge, si tiene varias versiones de su aplicación en diferentes etapas de desarrollo.

      Por ejemplo, con el siguiente comando se publicará la revisión 1 de la Snap Hello World en el canal stable:

      • snapcraft release helloworld 1 stable

      Visualizará un resultado similar al siguiente:

      Output

      Track Arch Channel Version Revision latest amd64 stable 1.0 1 candidate ^ ^ beta ^ ^ edge ^ ^ The 'stable' channel is now open.

      Ahora puede buscar su aplicación en la Snap Store e instalarla en cualquiera de sus dispositivos.

      Tienda de Snapcraft con la aplicación HelloWord n los resultados de búsqueda

      En este paso final, subió su paquete de Snap compilado a la Snap Store y lo puso a disponibilidad del público en general.

      Conclusión

      A través de este artículo, configuró y compiló una aplicación Snap, y luego la publicó a través de la Snap Store. Ahora tiene el conocimiento básico necesario para realizar el mantenimiento de su aplicación y crear nuevas aplicaciones.

      Si desea explorar las Snaps en mayor profundidad, es posible que desee recorrer toda la Snap Store. Es posible que desee revisar la Referencia YAML de Snapcraft para comprender mejor el tema e identificar atributos adicionales para la configuración de su Snap.

      Por último, si desea obtener más información sobre el desarrollo de Snaps, le gustará leer material sobre enlaces de Snap e implementarlos; estos permiten que los Snaps reaccionen de forma dinámica a los cambios del sistema, como las actualizaciones o los ajustes de las políticas de seguridad.



      Source link

      How To Use the PDO PHP Extension to Perform MySQL Transactions in PHP on Ubuntu 18.04


      The author selected Open Sourcing Mental Illness to receive a donation as part of the Write for DOnations program.

      Introduction

      A MySQL transaction is a group of logically related SQL commands that are executed in the database as a single unit. Transactions are used to enforce ACID (Atomicity, Consistency, Isolation, and Durability) compliance in an application. This is a set of standards that govern the reliability of processing operations in a database.

      Atomicity ensures the success of related transactions or a complete failure if an error occurs. Consistency guarantees the validity of the data submitted to the database according to defined business logic. Isolation is the correct execution of concurrent transactions ensuring the effects of different clients connecting to a database do not affect each other. Durability ensures that logically related transactions remain in the database permanently.

      SQL statements issued via a transaction should either succeed or fail altogether. If any of the queries fails, MySQL rolls back the changes and they are never committed to the database.

      A good example to understand how MySQL transactions work is an e-commerce website. When a customer makes an order, the application inserts records into several tables, such as: orders and orders_products, depending on the business logic. Multi-table records related to a single order must be atomically sent to the database as a single logical unit.

      Another use-case is in a bank application. When a client is transferring money, a couple of transactions are sent to the database. The sender’s account is debited and the receiver’s party account is credited. The two transactions must be committed simultaneously. If one of them fails, the database will revert to its original state and no changes should be saved to disk.

      In this tutorial, you will use the PDO PHP Extension, which provides an interface for working with databases in PHP, to perform MySQL transactions on an Ubuntu 18.04 server.

      Prerequisites

      Before you begin, you will need the following:

      Step 1 — Creating a Sample Database and Tables

      You’ll first create a sample database and add some tables before you start working with MySQL transactions. First, log in to your MySQL server as root:

      When prompted, enter your MySQL root password and hit ENTER to proceed. Then, create a database, for the purposes of this tutorial we’ll call the database sample_store:

      • CREATE DATABASE sample_store;

      You will see the following output:

      Output

      Query OK, 1 row affected (0.00 sec)

      Create a user called sample_user for your database. Remember to replace PASSWORD with a strong value:

      • CREATE USER 'sample_user'@'localhost' IDENTIFIED BY 'PASSWORD';

      Issue full privileges for your user to the sample_store database:

      • GRANT ALL PRIVILEGES ON sample_store.* TO 'sample_user'@'localhost';

      Finally, reload the MySQL privileges:

      You’ll see the following output once you’ve created your user:

      Output

      Query OK, 0 rows affected (0.01 sec) . . .

      With the database and user in place, you can now create several tables for demonstrating how MySQL transactions work.

      Log out from the MySQL server:

      Once the system logs you out, you will see the following output:

      Output

      Bye.

      Then, log in with the credentials of the sample_user you just created:

      • sudo mysql -u sample_user -p

      Enter the password for the sample_user and hit ENTER to proceed.

      Switch to the sample_store to make it the currently selected database:

      You’ll see the following output once it is selected:

      Output

      Database Changed.

      Next, create a products table:

      • CREATE TABLE products (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50), price DOUBLE) ENGINE = InnoDB;

      This command creates a products table with a field named product_id. You use a BIGINT data type that can accommodate a large value of up to 2^63-1. You use this same field as a PRIMARY KEY to uniquely identify products. The AUTO_INCREMENT keyword instructs MySQL to generate the next numeric value as new products are inserted.

      The product_name field is of type VARCHAR that can hold up to a maximum of 50 letters or numbers. For the product price, you use a DOUBLE data type to cater for floating point formats in prices with decimal numbers.

      Lastly, you use the InnoDB as the ENGINE because it comfortably supports MySQL transactions as opposed to other storage engines such as MyISAM.

      Once you’ve created your products table, you’ll get the following output:

      Output

      Query OK, 0 rows affected (0.02 sec)

      Next, add some items to the products table by running the following commands:

      • INSERT INTO products(product_name, price) VALUES ('WINTER COAT','25.50');
      • INSERT INTO products(product_name, price) VALUES ('EMBROIDERED SHIRT','13.90');
      • INSERT INTO products(product_name, price) VALUES ('FASHION SHOES','45.30');
      • INSERT INTO products(product_name, price) VALUES ('PROXIMA TROUSER','39.95');

      You’ll see output similar to the following after each INSERT operation:

      Output

      Query OK, 1 row affected (0.02 sec) . . .

      Then, verify that the data was added to the products table:

      You will see a list of the four products that you have inserted:

      Output

      +------------+-------------------+-------+ | product_id | product_name | price | +------------+-------------------+-------+ | 1 | WINTER COAT | 25.5 | | 2 | EMBROIDERED SHIRT | 13.9 | | 3 | FASHION SHOES | 45.3 | | 4 | PROXIMA TROUSER | 39.95 | +------------+-------------------+-------+ 4 rows in set (0.01 sec)

      Next, you’ll create a customers table for holding basic information about customers:

      • CREATE TABLE customers (customer_id BIGINT PRIMARY KEY AUTO_INCREMENT, customer_name VARCHAR(50) ) ENGINE = InnoDB;

      As in the products table, you use the BIGINT data type for the customer_id and this will ensure the table can support a lot of customers up to 2^63-1 records. The keyword AUTO_INCREMENT increments the value of the columns once you insert a new customer.

      Since the customer_name column accepts alphanumeric values, you use VARCHAR data type with a limit of 50 characters. Again, you use the InnoDB storage ENGINE to support transactions.

      After running the previous command to create the customers table, you will see the following output:

      Output

      Query OK, 0 rows affected (0.02 sec)

      You’ll add three sample customers to the table. Run the following commands:

      • INSERT INTO customers(customer_name) VALUES ('JOHN DOE');
      • INSERT INTO customers(customer_name) VALUES ('ROE MARY');
      • INSERT INTO customers(customer_name) VALUES ('DOE JANE');

      Once the customers have been added, you will see an output similar to the following:

      Output

      Query OK, 1 row affected (0.02 sec) . . .

      Then, verify the data in the customers table:

      You’ll see a list of the three customers:

      Output

      +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 1 | JOHN DOE | | 2 | ROE MARY | | 3 | DOE JANE | +-------------+---------------+ 3 rows in set (0.00 sec)

      Next, you’ll create an orders table for recording orders placed by different customers. To create the orders table, execute the following command:

      • CREATE TABLE orders (order_id BIGINT AUTO_INCREMENT PRIMARY KEY, order_date DATETIME, customer_id BIGINT, order_total DOUBLE) ENGINE = InnoDB;

      You use the column order_id as the PRIMARY KEY. The BIGINT data type allows you to accommodate up to 2^63-1 orders and will auto-increment after each order insertion. The order_date field will hold the actual date and time the order is placed and hence, you use the DATETIME data type. The customer_id relates to the customers table that you created previously.

      You will see the following output:

      Output

      Query OK, 0 rows affected (0.02 sec)

      Since a single customer’s order may contain multiple items, you need to create an orders_products table to hold this information.

      To create the orders_products table, run the following command:

      • CREATE TABLE orders_products (ref_id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, product_id BIGINT, price DOUBLE, quantity BIGINT) ENGINE = InnoDB;

      You use the ref_id as the PRIMARY KEY and this will auto-increment after each record insertion. The order_id and product_id relate to the orders and the products tables respectively. The price column is of data type DOUBLE in order to accommodate floating values.

      The storage engine InnoDB must match the other tables created previously since a single customer’s order will affect multiple tables simultaneously using transactions.

      Your output will confirm the table’s creation:

      Output

      Query OK, 0 rows affected (0.02 sec)

      You won’t be adding any data to the orders and orders_products tables for now but you’ll do this later using a PHP script that implements MySQL transactions.

      Log out from the MySQL server:

      Your database schema is now complete and you’ve populated it with some records. You’ll now create a PHP class for handling database connections and MySQL transactions.

      Step 2 — Designing a PHP Class to Handle MySQL Transactions

      In this step, you will create a PHP class that will use PDO (PHP Data Objects) to handle MySQL transactions. The class will connect to your MySQL database and insert data atomically to the database.

      Save the class file in the root directory of your Apache web server. To do this, create a DBTransaction.php file using your text editor:

      • sudo nano /var/www/html/DBTransaction.php

      Then, add the following code to the file. Replace PASSWORD with the value you created in Step 1:

      /var/www/html/DBTransaction.php

      <?php
      
      class DBTransaction
      {
          protected $pdo;
          public $last_insert_id;
      
          public function __construct()
          {
              define('DB_NAME', 'sample_store');
              define('DB_USER', 'sample_user');
              define('DB_PASSWORD', 'PASSWORD');
              define('DB_HOST', 'localhost');
      
              $this->pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
              $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
              $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
          }
      

      Toward the beginning of the DBTransaction class, the PDO will use the constants (DB_HOST, DB_NAME, DB_USER, and DB_PASSWORD) to initialize and connect to the database that you created in step 1.

      Note: Since we are demonstrating MySQL transactions in a small scale here, we have declared the database variables in the DBTransaction class. In a large production project, you would normally create a separate configuration file and load the database constants from that file using a PHP require_once statement.

      Next, you set two attributes for the PDO class:

      • ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION: This attribute instructs PDO to throw an exception if an error is encountered. Such errors can be logged for debugging.
      • ATTR_EMULATE_PREPARES, false: This option disables emulation of prepared statements and allows the MySQL database engine to prepare the statements itself.

      Now add the following code to your file to create the methods for your class:

      /var/www/html/DBTransaction.php

      . . .
          public function startTransaction()
          {
              $this->pdo->beginTransaction();
          }
      
          public function insertTransaction($sql, $data)
          {
              $stmt = $this->pdo->prepare($sql);
              $stmt->execute($data);
              $this->last_insert_id = $this->pdo->lastInsertId();
          }
      
          public function submitTransaction()
          {
              try {
                  $this->pdo->commit();
              } catch(PDOException $e) {
                  $this->pdo->rollBack();
                  return false;
              }
      
                return true;
          }
      }
      

      Save and close the file by pressing CTRL + X, Y, then ENTER.

      To work with MySQL transactions, you create three main methods in the DBTransaction class; startTransaction, insertTransaction, and submitTransaction.

      • startTransaction: This method instructs PDO to start a transaction and turns auto-commit off until a commit command is issued.

      • insertTransaction : This method takes two arguments. The $sql variable holds the SQL statement to be executed while the $data variable is an array of the data to be bound to the SQL statement since you’re using prepared statements. The data is passed as an array to the insertTransaction method.

      • submitTransaction : This method commits the changes to the database permanently by issuing a commit() command. However, if there is an error and the transactions have a problem, the method calls the rollBack() method to revert the database to its original state in case a PDO exception is raised.

      Your DBTransaction class initializes a transaction, prepares the different SQL commands to be executed, and finally commits the changes to the database atomically if there are no issues, otherwise, the transaction is rolled back. In addition, the class allows you to retrieve the record order_id you just created by accessing the public property last_insert_id.

      The DBTransaction class is now ready to be called and used by any PHP code, which you’ll create next.

      Step 3 — Creating a PHP Script to Use the DBTransaction Class

      You’ll create a PHP script that will implement the DBTransaction class and send a group of SQL commands to the MySQL database. You’ll mimic the workflow of a customer’s order in an online shopping cart.

      These SQL queries will affect the orders and the orders_products tables. Your DBTransaction class should only allow changes to the database if all of the queries are executed without any errors. Otherwise, you’ll get an error back and any attempted changes will roll back.

      You are creating a single order for the customer JOHN DOE identified with customer_id 1. The customer’s order has three different items with differing quantities from the products table. Your PHP script takes the customer’s order data and submits it into the DBTransaction class.

      Create the orders.php file:

      • sudo nano /var/www/html/orders.php

      Then, add the following code to the file:

      /var/www/html/orders.php

      <?php
      
      require("DBTransaction.php");
      
      $db_host = "database_host";
      $db_name = "database_name";
      $db_user = "database_user";
      $db_password = "PASSWORD";
      
      $customer_id = 2;
      
      $products[] = [
        'product_id' => 1,
        'price' => 25.50,
        'quantity' => 1
      ];
      
      $products[] = [
        'product_id' => 2,
        'price' => 13.90,
        'quantity' => 3
      ];
      
      $products[] = [
        'product_id' => 3,
        'price' => 45.30,
        'quantity' => 2
      ];
      
      $transaction = new DBTransaction($db_host, $db_user, $db_password, $db_name);
      

      You’ve created a PHP script that initializes an instance of the DBTransaction class that you created in Step 2.

      In this script, you include the DBTransaction.php file and you initialize the DBTransaction class. Next, you prepare a multi-dimensional array of all the products the customer is ordering from the store. You also invoke the startTransaction() method to start a transaction.

      Next add the following code to finish your orders.php script:

      /var/www/html/orders.php

      . . .
      $order_query = "insert into orders (order_id, customer_id, order_date, order_total) values(:order_id, :customer_id, :order_date, :order_total)";
      $product_query = "insert into orders_products (order_id, product_id, price, quantity) values(:order_id, :product_id, :price, :quantity)";
      
      $transaction->insertQuery($order_query, [
        'customer_id' => $customer_id,
        'order_date' => "2020-01-11",
        'order_total' => 157.8
      ]);
      
      $order_id = $transaction->last_insert_id;
      
      foreach ($products as $product) {
        $transaction->insertQuery($product_query, [
          'order_id' => $order_id,
          'product_id' => $product['product_id'],
          'price' => $product['price'],
          'quantity' => $product['quantity']
        ]);
      }
      
      $result = $transaction->submit();
      
      if ($result) {
          echo "Records successfully submitted";
      } else {
          echo "There was an error.";
      }
      
      

      Save and close the file by pressing CTRL + X, Y, then ENTER.

      You prepare the command to be inserted to the orders table via the insertTransaction method. After this, you retrieve the value of the public property last_insert_id from the DBTransaction class and use it as the $order_id.

      Once you have an $order_id, you use the unique ID to insert the customer’s order items to the orders_products table.

      Finally, you call the method submitTransaction to commit the entire customer’s order details to the database if there are no problems. Otherwise, the method submitTransaction will rollback the attempted changes.

      Now you’ll run the orders.php script in your browser. Run the following and replace your-server-IP with the public IP address of your server:

      http://your-server-IP/orders.php

      You will see confirmation that the records were successfully submitted:

      PHP Output from MySQL Transactions Class

      Your PHP script is working as expected and the order together with the associated order products were submitted to the database atomically.

      You’ve run the orders.php file on a browser window. The script invoked the DBTransaction class which in turn submitted the orders details to the database. In the next step, you will verify if the records saved to the related database tables.

      Step 4 — Confirming the Entries in Your Database

      In this step, you’ll check if the transaction initiated from the browser window for the customer’s order was posted to the database tables as expected.

      To do this, log in to your MySQL database again:

      • sudo mysql -u sample_user -p

      Enter the password for the sample_user and hit ENTER to continue.

      Switch to the sample_store database:

      Ensure the database is changed before proceeding by confirming the following output:

      Output

      Database Changed.

      Then, issue the following command to retrieve records from the orders table:

      This will display the following output detailing the customer’s order:

      Output

      +----------+---------------------+-------------+-------------+ | order_id | order_date | customer_id | order_total | +----------+---------------------+-------------+-------------+ | 1 | 2020-01-11 00:00:00 | 2 | 157.8 | +----------+---------------------+-------------+-------------+ 1 row in set (0.00 sec)

      Next, retrieve the records from the orders_products table:

      • SELECT * FROM orders_products;

      You’ll see output similar to the following with a list of products from the customer’s order:

      Output

      +--------+----------+------------+-------+----------+ | ref_id | order_id | product_id | price | quantity | +--------+----------+------------+-------+----------+ | 1 | 1 | 1 | 25.5 | 1 | | 2 | 1 | 2 | 13.9 | 3 | | 3 | 1 | 3 | 45.3 | 2 | +--------+----------+------------+-------+----------+ 3 rows in set (0.00 sec)

      The output confirms that the transaction was saved to the database and your helper DBTransaction class is working as expected.

      Conclusion

      In this guide, you used the PHP PDO to work with MySQL transactions. Although this is not a conclusive article on designing an e-commerce software, it has provided an example for using MySQL transactions in your applications.

      To learn more about the MySQL ACID model, consider visiting the InnoDB and the ACID Model guide from the official MySQL website. Visit our MySQL content page for more related tutorials, articles, and Q&A.



      Source link

      How To Install MariaDB on Ubuntu 18.04


      Introduction

      MariaDB is an open-source database management system, commonly used as an alternative for the MySQL portion of the popular LAMP (Linux, Apache, MySQL, PHP/Python/Perl) stack. It is intended to be a drop-in replacement for MySQL.

      The short version of this installation guide consists of these three steps:

      • Update your package index using apt
      • Install the mariadb-server package using apt. The package also pulls in related tools to interact with MariaDB
      • Run the included mysql_secure_installation security script to restrict access to the server
      • sudo apt update
      • sudo apt install mariadb-server
      • sudo mysql_secure_installation

      This tutorial will explain how to install MariaDB on an Ubuntu 18.04 server, and verify that it is running and has a safe initial configuration.

      Prerequisites

      To follow this tutorial, you will need:

      Step 1 — Installing MariaDB

      On Ubuntu 18.04, MariaDB version 10.1 is included in the APT package repositories by default.

      To install it, update the package index on your server with apt:

      Then install the package:

      • sudo apt install mariadb-server

      These commands will install MariaDB, but will not prompt you to set a password or make any other configuration changes. Because the default configuration leaves your installation of MariaDB insecure, we will use a script that the mariadb-server package provides to restrict access to the server and remove unused accounts.

      Step 2 — Configuring MariaDB

      For new MariaDB installations, the next step is to run the included security script. This script changes some of the less secure default options. We will use it to block remote root logins and to remove unused database users.

      Run the security script:

      • sudo mysql_secure_installation

      This will take you through a series of prompts where you can make some changes to your MariaDB installation’s security options. The first prompt will ask you to enter the current database root password. Since we have not set one up yet, press ENTER to indicate “none”.

      The next prompt asks you whether you’d like to set up a database root password. Type N and then press ENTER. On Ubuntu, the root account for MariaDB is tied closely to automated system maintenance, so we should not change the configured authentication methods for that account. Doing so would make it possible for a package update to break the database system by removing access to the administrative account. Later, we will cover how to optionally set up an additional administrative account for password access if socket authentication is not appropriate for your use case.

      From there, you can press Y and then ENTER to accept the defaults for all the subsequent questions. This will remove some anonymous users and the test database, disable remote root logins, and load these new rules so that MariaDB immediately implements the changes you have made.

      Step 3 — (Optional) Adjusting User Authentication and Privileges

      On Ubuntu systems running MariaDB 10.1, the root MariaDB user is set to authenticate using the unix_socket plugin by default rather than with a password. This allows for some greater security and usability in many cases, but it can also complicate things when you need to allow an external program (e.g., phpMyAdmin) administrative rights.

      Because the server uses the root account for tasks like log rotation and starting and stopping the server, it is best not to change the root account’s authentication details. Changing credentials in the /etc/mysql/debian.cnf configuration file may work initially, but package updates could potentially overwrite those changes. Instead of modifying the root account, the package maintainers recommend creating a separate administrative account for password-based access.

      To do so, we will create a new account called admin with the same capabilities as the root account, but configured for password authentication. To do this, open up the MariaDB prompt from your terminal:

      Now, we will create a new user with root privileges and password-based access. Change the username and password to match your preferences:

      • GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;

      Flush the privileges to ensure that they are saved and available in the current session:

      Following this, exit the MariaDB shell:

      Finally, let’s test the MariaDB installation.

      Step 4 — Testing MariaDB

      When installed from the default repositories, MariaDB should start running automatically. To test this, check its status.

      • sudo systemctl status mariadb

      You’ll receive output that is similar to the following:

      Output

      ● mariadb.service - MariaDB 10.1.44 database server Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-03-25 16:51:16 UTC; 8min ago Docs: man:mysqld(8) https://mariadb.com/kb/en/library/systemd/ Main PID: 22559 (mysqld) Status: "Taking your SQL requests now..." Tasks: 27 (limit: 1152) CGroup: /system.slice/mariadb.service └─22559 /usr/sbin/mysqld Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: mysql Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: performance_schema Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: Phase 6/7: Checking and upgrading tables Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: Processing databases Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: information_schema Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: performance_schema Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: Phase 7/7: Running 'FLUSH PRIVILEGES' Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22596]: OK Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22658]: Checking for insecure root accounts. Mar 25 16:51:17 ubuntu-mariadb /etc/mysql/debian-start[22663]: Triggering myisam-recover for all MyISAM tables and aria-recover for all Aria tables

      If MariaDB isn’t running, you can start it with the command sudo systemctl start mariadb.

      For an additional check, you can try connecting to the database using the mysqladmin tool, which is a client that lets you run administrative commands. For example, this command says to connect to MariaDB as root and return the version using the Unix socket:

      You should receive output similar to this:

      Output

      mysqladmin Ver 9.1 Distrib 10.1.44-MariaDB, for debian-linux-gnu on x86_64 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Server version 10.1.44-MariaDB-0ubuntu0.18.04.1 Protocol version 10 Connection Localhost via UNIX socket UNIX socket /var/run/mysqld/mysqld.sock Uptime: 10 min 9 sec Threads: 1 Questions: 445 Slow queries: 0 Opens: 167 Flush tables: 1 Open tables: 30 Queries per second avg: 0.730

      If you configured a separate administrative user with password authentication, you could perform the same operation by typing:

      • mysqladmin -u admin -p version

      This means that MariaDB is up and running and that your user is able to authenticate successfully.

      Conclusion

      In this guide you installed MariaDB to act as an SQL server. During the installation process you also secured the server. Optionally, you also created a separate password-authenticated administrative user.

      Now that you have a running and secure MariaDB server, here some examples of next steps that you can take to work with the server:

      You can also incorporate MariaDB into a larger application stack:



      Source link