Blog Mysql PHP Programação
Mysql com C/Lazarus/Python/PHP/R – Parte 3

Seguindo com nossos artigos, irei incluir agora uma aplicação em PHP, consumindo Mysql.

Este artigo é o terceiro, sobre esse tema, onde irei abordar o uso do mysql em diversas linguagens.

Neste artigo especifíco abordarei o uso no PHP.

GITHUB

Iremos criar em nosso projeto:

https://github.com/marcelomaurin/mysql-vs-todos

Será criado uma pasta chamada PHP, esta pasta, conterá o material necessário para rodar a aplicação.

Pré requisitos

Instale os seguintes pacotes em sua máquina Ubuntu

apt install apache2

Instale os pacotes

apt install php libapache2-mod-php php7.4-mysql php7.4-common php7.4-mysql php7.4-xml php7.4-xmlrpc php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip php7.4-intl -y

apt install python3-certbot-apache

Pronto instalação realizada com sucesso, conforme a contraprova.

PHP recem instalado

Criação dos códigos

Criação da Página Principal

Usaremos como interface o boot strap, para gerar uma interface bonita e simples de usar.

Usaremos o modelo MVC (Model , View , Control), que divide a página em 3 partes.

Abordarei o projeto em detalhes parte a parte.

Sempre lembrando que os fontes encontram-se no git.

Para visualização de como ficará no PHP, podemos acessar o link:

http://maurinsoft.com.br/exemplos/phpmysql/

Atribuíndo a conexão

A conexão de todos os scripts são definidos pelo código connectdb.php, conforme fragmento abaixo:

<?php
	define("HOSTNAME","localhost");
	define("USERNAME","php");
 	define("PASSWORD","123456");
	define("DATABASE","testedb");
?>

$dbhandle = new mysqli(HOSTNAME, USERNAME, PASSWORD, DATABASE) or die("Erro ao conectar no banco de dados");

Nele definimos as definições de conexão que podemos chamar nos demais programas.

Web Service do PHP

Acesso a base de Pessoas, eu criei um web service bem simples.

Meu web service possui 4 serviços:

  • dPessoa.php – Apaga um registro
  • iPessoa.php – Inclui um registro de pessoa
  • sPessoa.php – Pesquisa um conjunto de pessoas
  • uPessoa.php – Atualiza o cadastro de uma pessoa.

O Serviço pode ser visto no caminho:

http://maurinsoft.com.br/exemplos/phpmysql/ws/

Todos os web services são baseados em GET para obter os parametros, segue o código do sPessoa.php:

<?php<?php
    /*phpinfo();*/
	/*Registra webservice para processamento de jobs*/
	ini_set('display_errors', 'Off');
	error_reporting(E_ALL);

	include "connectdb.php";

	//header('Cache-Control: no-cache, must-revalidate');
	//$data = var_dump(json_decode(file_get_contents("php://input")));
	$data = json_decode(file_get_contents("php://input"));
	if($data){
		$idpessoa = $dbhandle->real_escape_string($data->idpessoa);
		$nome = $dbhandle->real_escape_string($data->nome);
		$profissao = $dbhandle->real_escape_string($data->profissao);
		$sexo = $dbhandle->real_escape_string($data->sexo);
		$dtnasc = $dbhandle->real_escape_string($data->dtnasc);
	} else {
		$idpessoa = $dbhandle->real_escape_string($_GET['idpessoa']);
		$nome = $dbhandle->real_escape_string($_GET['nome']);
		$profissao = $dbhandle->real_escape_string($data->profissao);
		$sexo = $dbhandle->real_escape_string($data->sexo);
		$dtnasc = $dbhandle->real_escape_string($data->dtnasc);
	}


	$query = "select * from pessoas";
	$sqlwhere = "";
	if(!empty($idpessoa)){
		$sqlwhere = " where (idpessoa = ".$idpessoa.");";
	}
	if(!empty($nome)){
		if($sqlwhere){
			$sqlwhere = $sqlwhere." and (nome like '%".$nome."%');";
		} else {
			$sqlwhere = " where (nome like '%".$nome."%');";
		}
	}
	if(!empty($profissao)){
		if($sqlwhere){
			$sqlwhere = $sqlwhere." and (profissao like '%".$profissao."%');";
		} else {
			$sqlwhere = " where (profissao like '%".$profissao."%');";
		}
	}
	if(!empty($sexo)){
		if($sqlwhere){
			$sqlwhere = $sqlwhere." and (sexo = '".$sexo."');";
		} else {
			$sqlwhere = " where (sexo = '".$sexo."');";
		}
	}
	if(!empty($dtnasc)){
		if($sqlwhere){
			$sqlwhere = $sqlwhere." and (dtnasc = '".$dtnasc."');";
		} else {
			$sqlwhere = " where (dtnasc = '".$dtnasc."');";
		}
	}
	$query = $query . $sqlwhere;

	//echo $query."<br/>";

	$rs = $dbhandle->query($query);

	//print json_encode($rs);

	$cont = 0;

	echo '{"rs":[';
	$row=$rs->fetch_assoc();
	if($row){
		do
		{
			if($cont!=0)
			{
				echo ',';
			}
			echo '{';
			echo '"idpessoa":"'.$row['idPessoa'].'",';
			echo '"nome":"'.$row['nome'].'",';
			echo '"profissao":"'.$row['profissao'].'",';
			echo '"dtnasc":"'.$row['dtnasc'].'",';
			echo '"sexo":"'.$row['sexo'].'"';
			echo '}';
			$cont ++;
		} while($row=$rs->fetch_assoc());
	}
	echo ']}';
	if ($cont>0)
	{
		echo($strJSON);
	}


?>

Neste fragmento, temos um web service muito simplificado.

Onde criamos uma conexão com o banco de dados,

No proximo passo, capturamos os parametros, que podem ser 4:

  • idpessoa – codigo do registro que será pesquisado
  • nome – nome da pessoa que será pesquisada
  • profissão – profissao da pessoa que será pesquisada
  • sexo – Sexo da pessoa que será pesquisada

Os parametros passados, podem ou não retornar um unico registro.

Por fim o json é montado, convertendo o conjunto de itens encontrados em uma expressão json.

Para testar o web service, é necessário rodar conforme o link.

Exemplo de JSON criado

Visualização

Select

http://maurinsoft.com.br/exemplos/phpmysql/ws/sPessoa.php?idpessoa=1

Insert

http://maurinsoft.com.br/exemplos/phpmysql/ws/iPessoa.php?nome=Marcelo&dtnasc=2021-01-01&profissao=Analista&sexo=M

Delete

http://maurinsoft.com.br/exemplos/phpmysql/ws/dPessoa.php?nome=Marcelo

Update

http://maurinsoft.com.br/exemplos/phpmysql/ws/uPessoa.php?pesnome=Marcelo&nome=Marcella&profissao=Tecnica Informatica&sexo=F&dtnasc=2002-01-16

Front End

O index.php – e o front end, ele é responsável pela troca de informações entre o browser e os demais componentes.

Link do front end:

http://maurinsoft.com.br/exemplos/phpmysql/index.php

Segue o formulario:

No Front End, desenvolvido no modelo MVC, criamos 3 elementos.

O index.php, que mostrará as informações encontradas.


<?php
  //Controla o Debug no projeto
  ini_set('display_errors', 'On');

  include "sessao.php";
  include "config.php";
  include "funcs.php";
?>

<html>
	<header>
		<title>Cadastro de Pessoas</title>
		<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
		<!-- Latest compiled and minified CSS -->
		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

		<!-- jQuery library -->
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

		<!-- Latest compiled JavaScript -->
		<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

	</header>
	<body>


		<div ng-app="Pessoas" ng-controller="cntrl" >
			<div class="container-fluid bg-1 text-rigth">
				<form action="">
					<?  Pesquisar Itens ?>
					<div class="jumbotron">
							<h1>Cadastro de Pessoas</h1>
							<p>Modelo de aplicação MVC, conforme <a href="http://maurinsoft.com.br/index.php/2022/02/04/mysql-com-c-lazarus-python-php-r-parte-3/">Artigo publicado.</a></p>
							<p>Para maiores informações <a href="mailto:marcelomaurinmartins@gmail.com">marcelomaurinmartins@gmail.com</a></p>
					</div>
					<div class="row">
						<div class="col-sm-1">idPessoa:</div>
						<div class="col-sm-2"><input class="form-control" placeholder="idPessoa (opcional)" type="text" ng-model="pidpessoa" name="pidpessoa"></div>
					</div>
					<div class="separador">
					</div>
					<div class="row">
						<div class="col-sm-1">Nome:</div>
						<div class="col-sm-4"><input class="form-control" placeholder="nome (opcional)" type="text" ng-model="pnome" name="pnome"></div>
					</div>
					<div class="separador">
					</div>

					<div class="row">
						<div class="col-sm-1">Profissão:</div>
						<div class="col-sm-4"><input class="form-control" placeholder="profissao (opcional)" type="text" ng-model="pprofissao" name="pprofissao"></div>
					</div>
					<div class="separador">
					</div>
					<div class="row">
					    <div class="col-sm-1">Dt. Nascimento:</div>
						<div class="col-sm-4"><input class="form-control" placeholder="dt Nascimento (yyyy-mm-dd) (opcional)" type="text" ng-model="pdtnasc" name="pdtnasc"></div>
					</div>
					<div class="separador">
					<div class="row">
					    <div class="col-sm-1">Sexo:</div>
						<div class="col-sm-4"><input class="form-control" placeholder="Genero sexual (M/F) (opcional)" type="text" ng-model="psexo" name="psexo"></div>
					</div>
					<div class="separador">
					</div>
					<div class="row">
						<div class="col-sm-1"></div>
						<div class="col-sm-4"></div>
						<div class="col-sm-1"> <input type="button" class="btn btn-primary"  value="Pesquisar" ng-click="displayPessoa(pidpessoa,pnome,pprofissao,psexo,pdtnasc)" > </div>
						<div class="col-sm-1">  </div>
						<div class="col-sm-1"> <input type="button" class="btn btn-primary"  value="Novo Item" ng-click="newPessoa(pidpessoa)" > </div>

					</div>


					<? Retorno de mensagem de erro ?>
					<div class="info">
						<div class="control-label">Alerta:</div>
						<div class="info">{{msg}}</div>
					</div>
				<input type="hidden" name="trp-form-language" value="en"/></form>
			</div>
			<? layout da tabela de resposta ?>
			<div class="container-fluid bg-1 text-rigth">

				<? **Cadastrar itens** ?>
				<div id="cadastro" ng-style="disableInsert" >
					<div class="row">
						<div class="col-sm-12"> <h3>Operação Insert registro </h3></div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label"> Nome: </div>
						<div class="col-sm-4"> <input  class="form-control" placeholder=" Nome da pessoa" type="text" ng-model="nome" name="nome"> </div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label"> Profissão</div>
						<div class="col-sm-4"> <input class="form-control"  placeholder=" Profissão da pessoa" type="text" ng-model="profissao" name="profissao"></div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label"> Dt. Nascimento</div>
						<div class="col-sm-4"> <input class="form-control"  placeholder=" Dt nascimento (YYYY-mm-dd)" type="text" ng-model="dtnasc" name="dtnasc"></div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label">Sexo</div>
						<div class="col-sm-4"> <input class="form-control"  placeholder=" Sexo de Nascimento (M/F)" type="text" ng-model="sexo" name="sexo"></div>
					</div>
					<div class="row">
						<div class="col-sm-4"></div>
						<div class="col-sm-1 control-label">  </div>
						<div> <input type="button" class="btn btn-primary" value="submit" ng-click="insertPessoa()" > </div>
					</div>
				</div>
			</div>

			<div class="container-fluid bg-1 text-rigth">

				<? *** Update *** ?>
				<div id="edicao" ng-style="disableUpdate" class="container-fluid bg-1 text-rigth">
					<div class="row">
						<div class="col-sm-12"> <h3>Operacao de Edicao</h3></div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label"> idPessoa:</div><div> {{edidpessoa}}</div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label"> Nome</div>
						<div class="col-sm-4"> <input class="form-control"  type="text" ng-model="ednome" name="ednome"></div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label"> Profissão</div>
						<div class="col-sm-4"> <input class="form-control"  type="text" ng-model="edprofissao" name="edprofissao"></div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label"> Dt. Nascimento</div>
						<div class="col-sm-4"> <input class="form-control"  type="text" ng-model="eddtnasc" name="eddtnasc"></div>
					</div>
					<div class="row">
						<div class="col-sm-1 control-label">Sexo</div>
						<div class="col-sm-4"> <input class="form-control"  type="text" ng-model="edsexo" name="edsexo"></div>
					</div>
					<div class="row">
						<div class="col-sm-4"></div>
						<div class="col-sm-1"> <button class="btn btn-primary" ng-click="updatePessoa(edidpessoa,ednome, edprofissao, eddtnasc, edsexo)">Atualizar</button></div>
					</div>
				</div>
			</div>

			<div class="container-fluid bg-1 text-rigth">
				<div class="row">
				<hr>
				</div>
			</div>

			<? ** Tela de Resultado **?>
			<div class="container-fluid bg-1 text-rigth">
				<table class="table table-striped">
					<thead>
						<tr>
							<th>IdPessoa</th>
							<th>Nome</th>
							<th>Profissão</th>
							<th>Dt. Nascimento</th>
							<th>Sexo</th>

						<tr>
					</thead>
					<tbody>
						<tr ng-repeat="dados in data.rs">
							<td>{{dados.idpessoa}}</td>
							<td>{{dados.nome}}</td>
							<td>{{dados.profissao}}</td>
							<td>{{dados.dtnasc}}</td>
							<td>{{dados.sexo}}</td>
							<td><button class="btn btn-primary" ng-click="deletePessoa(dados.idpessoa);">Delete</button></td>
							<td><button class="btn btn-primary" ng-click="HabilitaEdicao(dados);">Edit</button></td>
						</tr>
					</tbody>
				</table>


			</div>



			<? *** Controler *** ?>
			<script>
				var app = angular.module('Pessoas',[]);
				app.controller('cntrl', function($scope,$http)
				{
				    $scope.disableUpdate = {'display': 'none'}; //Atribui Edicao invisivel
					$scope.disableInsert = {'display': 'none'}; //Atribui Edicao invisivel

					//Mostra  os Jobs
					$scope.insertPessoa=function()
					{
						$http.post("/exemplos/phpmysql/ws/iPessoa.php",{'nome':$scope.nome,'profissao':$scope.profissao,'dtnasc':$scope.dtnasc,'sexo':$scope.sexo})
						.success(function()
						{
							$scope.msg = "nome foi cadastrado com sucesso";
							$scope.displayPessoa();
						})
					}

					$scope.displayPessoa=function(pidpessoa,pnome,pprofissao,psexo,pdtnasc)
					{
					    $scope.disableUpdate = {'display': 'none'}; //Atribui Edicao invisivel
						$scope.disableInsert = {'display': 'none'}; //Atribui Edicao invisivel

						if (typeof pidpessoa == "undefined")
						{
							pidpessoa = "";
						}
						if (typeof pnome == "undefined")
						{
							pnome = "";
						}
						if (typeof psexo == "undefined")
						{
							psexo = "";
						}
						if (typeof pprofissao == "undefined")
						{
							pprofissao = "";
						}
						if (typeof pdtnasc == "undefined")
						{
							pdtnasc = "";
						}

						var params = {"idpessoa": pidpessoa, "nome": pnome, "profissao": pprofissao, "sexo": psexo, "dtnasc": pdtnasc };
						var config = {params: params};


						$http.get("/exemplos/phpmysql/ws/sPessoa.php",config)
						.success(function(data)
						{
							$scope.data = data;
							$scope.msg = "Tela Atualizada!";
						})
						.error(function()
						{
							$scope.msg = "Pesquisa retornou vazia";
							$scope.data = null;
						})
					}

					$scope.deletePessoa=function(idpessoa)
					{
						$http.post("/exemplos/phpmysql/ws/dPessoa.php",{'idpessoa':idpessoa})
						.success(function()
						{
							$scope.displayPessoa();
							$scope.msg = "Registro excluido!";
						})
					}

					//Mostra  os Jobs
					$scope.newPessoa=function()
					{
						$scope.disableInsert = {'display': 'block'};
						$scope.disableUpdate = {'display': 'none'};
						$scope.edidpessoa = "";
						$scope.ednome = "";

					}

					$scope.HabilitaEdicao=function(dado)
					{
						$scope.disableUpdate = {'display': 'block'};
						$scope.edidpessoa = dado.idpessoa;
						$scope.ednome = dado.nome;
					}


					$scope.updatePessoa=function(edidpessoa, ednome, edprofissao, eddtnasc, edsexo)
					{
						$http.post("/exemplos/phpmysql/ws/uPessoa.php",{'pesidpessoa':edidpessoa,'nome':ednome,'profissao':edprofissao,'dtnasc':eddtnasc,'sexo':edsexo})
						.success(function()
						{
							$scope.displayPessoa();
							$scope.msg = "Registro excluido!";

							$scope.disableUpdate = {'display': 'none'};
							$scope.displayPessoa();
						})
					}

				});
			</script>


		</div>
	</body>
</html>

Podemos notar que todo o serviço pesado é realizado pelo web service, ficando a responsábilidade apenas do controler de consumir as informações passadas.

Não entrarei no detalhe técnico do PHP, nem em detalhes sobre o modelo MVC.

Deixarei tal atividade para um post em momento oportuno.

Conclusão

O PHP é uma linguagem robusta e intuitiva, permitindo escrita elegante de um código limpo e eficiente.

Eu no entanto, não me considero um programador excepcional em PHP, apenas quebro o galho, criando algumas páginas e cumprindo um papel menor.

O PHP é muito mais que apresentado aqui, porem sei que isso será suficiente para dar um norte para muitos.

Espero ter ajudado, e caso tenham gostado do artigo, mandem um email para mim.

,

Referências

https://www.cloudbooklet.com/how-to-install-lamp-apache-mysql-php-in-ubuntu-20-04/

https://getbootstrap.com/docs/5.1/examples/navbar-static/

Artigos Relacionados

    Blog Lazarus Programação
    Implementando uma Interface no Lazarus

    Vou apresentar aqui muito sutilmente um caso de construção de uma interface em Lazarus.

    Qual a diferença entre uma interface e uma classe.

    A Interface é como um contrato, onde se estabelece as conexões de saída (Métodos e propriedades) que serão utilizadas. Nela voce não precisa criar código, pois só estabelece quais serão as conexões.

    Ao criar uma classe, vc estabele as conexões porem tem que realizar uma série de codificações (implementation) que de fato não seriam necessárias. Pois a codificação fica a cargo da classe filha.

    Exemplo de projeto

    Desenvolvi uma interface no projeto da API da impressora.

    GIT do Projeto

    https://github.com/marcelomaurin/LIBESCPOS

    Exemplo de uso

    Na unit imp_generico.pas, estabelecemos a interface, que será herdada das demais classes.

      { TIMP_GENERICO }
      TIMP_GENERICO = interface
        ['{045F6EED-2C11-447D-A7DC-09DB995367C2}']
    
         function getserial : string;
         procedure setserial(value : string);
    
         function InitPrint(): string;
         function NewLine(): string;
         function LineText(Info : string): string;
         function Negrito(): string;
         function Normal(): string;
         function Sublinhado(): string;
         function DoubleTexto(): string;
         function beep(): string;
         function Guilhotina(): string;
         function AcionaGaveta(): string;
         function Barra1D(Info : string): string;
         function Barra2D(info : String): string;
         function loadImagem(X,Y : integer; Info : String): string;
         function imprimeImagem(X,Y : integer): string;
         property Serial : String read getserial  write setserial;
    end;                     

    No fonte imp_ELGINI9.pas, chamamos a interface, criando os métodos, realmente propostos na interface.

    type
    
     { TIMP_ELGINI9 }
    
     TIMP_ELGINI9 = class(TInterfacedObject,TIMP_GENERICO)
         FCOLUNA : integer;
         FSERIAL : String;
    
     private
         function getserial : string;
         procedure setserial(value : string);
    
    
     public
         constructor create();
         destructor destroy();
    
         function NewLine(): string;
         function InitPrint(): string;
         function LineText(Info : string): string;
         function beep(): string;
         function Negrito(): string;
         function Normal(): string;
         function Sublinhado(): string;
         function DoubleTexto(): string;
         function Guilhotina(): string;
         function AcionaGaveta(): string;
         function Barra2D(Info : string): string;
         function Barra1D(Info : string): string;
         function loadImagem(X,Y : integer;Info : String): string;
         function imprimeImagem(X,Y : integer): string;
         function Centralizado(): string;
         function PaginaM616(): string;
         function CorPg618(): string;
         function HabilitaArmazenaDados(): string;
         function Armazenadados( Info : string): string;
         function ImprimeQRCODEArmazenado(): string;
     published
         property Serial : String read getserial  write setserial;
    end;
    
    var
      IMPELGINI9: TIMP_ELGINI9;
    
    implementation          

    Omiti a implementation, para que o artigo não fique demasiado longo.

    Blog Delphi Lazarus
    Criando um GUID no Lazarus

    O GUID é um identificador unico Universal (Globally Unique Identifier), com ele é possível apontar de forma inequivoca uma aplicação ou serviço.

    No lazarus para criar um GUID no Lazarus ou Delphi, basta pressionar:

    <CTRL>+<SHIFT>+g

    Desta forma ele criará um numero como se segue.

    [‘{045F6EED-2C11-447D-A7DC-09DB995367C2}’]

    Exemplo de GUID

    Referências

    http://www.macoratti.net/d130402.htm

    Blog C/C++
    Instalando NCURSES

    NCURSES, conforme o wikipédia, fornece uma biblioteca que provê uma API para o desenvolvimento de interfaces em modo texto. Garante também uma otimização quanto as mudanças de telas, reduzindo a latência quando se utiliza acesso remoto via shells.

    Instalando o NCURSES

    Para instalar o ncurses é muito simples, basta digitar o comando abaixo:

    sudo apt-get install libncurses5-dev libncursesw5-dev

    Exemplo de instalação:

    Instalação do ncurses.

    Local das Libs

    Includes

    O include ou header da lib fica localizado em /us/include/ sendo o ncurses.h

    Exemplos

    Em /usr/lib/ncurses/exemples, fica um conjunto de exemplos, podem ser vistos e testados.

    São binários muito bons para testar.

    Principais funções

    São as principais funções:

    • initscr – Inicializa a tela
    • raw – Desativa buffer embutido
    • printw – imprime na tela
    • wprintw – imprime em posicao correta xy
    • clear – Limpa janela
    • getmaxyx – limites da janela
    • getyx – obtem posição do cursor
    • refresh – atualiza a tela
    • endwin – finaliza tela

    Referências

    https://www.garron.me/en/linux/install-ncurses-library-ubuntu-debian.html

    https://terminalroot.com.br/ncurses/

    Blog C/C++ Mysql Programação Shell Script
    Mysql com C/Lazarus/Python/PHP/R – Parte 2

    Neste segundo artigo iremos abordar como realizar um crud simples em C usando banco de dados Mysql como referência.

    No artigo anterior, tratamos de criar o banco de dados.

    http://maurinsoft.com.br/index.php/2022/01/31/mysql-com-c-lazarus-python-php-r-parte-1

    Agora iremos tratar de algumas definições do nosso projeto:

    Para facilitar o CRUD, iremos dividir em pequenos aplicativos, alias, essa divisão deixa muito didática e fácil de entender.

    • insPessoa.c – Inclui uma pessoa na tabela de pessoas
    • SelPessoa.c – Lista a relação de pessoas
    • UpdPessoa.c – Atualiza os dados de uma pessoa da tabela de pessoa
    • remPessoa.c – Remove uma pessoa da tabela de pessoas

    Com isso, finalizamos o crud e teremos alcançado nosso objetivo neste artigo.

    Dependências

    Iremos incluir aqui as dependências necessárias para seguir com este programa.

    Primeiro pedimos para seguir o primeiro tutorial, pois sem a instalação do mysql fica dificil implementar.

    Em seguida a instalação do ncurses, conforme o link abaixo:

    http://maurinsoft.com.br/index.php/2022/01/31/instalando-ncurses/

    GIT do Projeto

    Estaremos modificando o git incluindo a pasta gcc, nela incluiremos todos os fontes do projeto.

    https://github.com/marcelomaurin/mysql-vs-todos

    Inclusão dos fontes dos projetos em C

    Começa o Jogo!

    Primeiro iremos criar o Makefile

    
    CC=gcc
    SOURCE_INS=insPessoa.c
    SOURCE_SEL=selPessoa.c
    SOURCE_DEL=delPessoa.c
    SOURCE_UPD=updPessoa.c
    
    LIBS= -lmysql -lncurses
    
    TARGET_INS=insPessoas
    TARGET_SEL=selPessoas
    TARGET_DEL=delPessoas
    TARGET_UPD=updPessoas
    
    
    all: clean compile install
    
    clean:
    	rm *.o
    
    compile:
    	$(CC) $(SOURCE_INS) -o $(TARGET_INS)
    	$(CC) $(SOURCE_SEL) -o $(TARGET_SEL)
    	$(CC) $(SOURCE_DEL) -o $(TARGET_DEL)
    	$(CC) $(SOURCE_UPD) -o $(TARGET_UPD)
    
    
    install:
    	cp $(TARGET_INS) /usr/local/bin/
    	cp $(TARGET_SEL) /usr/local/bin/
    	cp $(TARGET_DEL) /usr/local/bin/
    	cp $(TARGET_UPD) /usr/local/bin/

    Ao chamar o make, iremos compilar todos os fontes incluindo eles na pasta /usr/local/bin, que permite executar em qualquer local que quisermos.

    Explicação do programa

    Este programa irei apresentar na integra, comentando os pontos principais.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <mysql.h>
    
    #define USER "gcc"
    #define HOST "localhost"
    #define DATABASE "testedb"
    #define PASS "123456"
    
    
    #define SUCCESS 0
    #define ERROR 1
    
    MYSQL *mycon;
    //char PASS[20];
    int res;
    
    int conecta(void){
    	mycon = mysql_init(NULL);
    	/*
    	mysql_real_connect(MYSQL *mysql,
                       const char *host,
                       const char *user,
                       const char *passwd,
                       const char *db,
                       unsigned int port,
                       const char *unix_socket,
                       unsigned long client_flag)
    				  */
        //mysql_options(mycon, MYSQL_READ_DEFAULT_FILE, (void *)"./my.cnf");
    	res = mysql_real_connect(
    				  mycon,
    				  HOST,
    				  USER,
    				  PASS,
    				  DATABASE,
    				  3306,
    				  NULL,
    				  0);
    	if(res!=NULL)
    	{
    		printf("Sucesso na conexão com servidor\n");
    		return SUCCESS;
    	}
    	else {
    		printf("Falha na conexao! Erro:%s\n",mysql_error(mycon));
    		return ERROR;
    	}
    }
    
    //Estrutura de cadastro de pessoas
    typedef struct PESSOAS {
      int idpessoa;
      char nome[30];
      char dtnasc[20];
      char profissao[20];
      char sexo;
    } PESSOAS;
    
    
    
    void desconecta(void){
       mysql_close(mycon);
       mysql_library_end();
       printf("Desconectado\n");
    }
    
    int Select( PESSOAS *pes){
      char sql[500];
      memset(sql,'\0',sizeof(sql));
      sprintf(sql,"select * from pessoas where nome like '%%%s%%'",
           pes->nome
    	 );
      printf("SQL:%s\n\n",sql);
      //mysql_prepare(
      res = mysql_query(mycon,sql);
      if(!res) {
    	  printf("Pesquisa com sucesso!\n");
    	  MYSQL_RES *result = mysql_store_result(mycon);
    
          if (!result) {
            printf("Couldn't get results set: %s\n", mysql_error(mycon));
          } else {
            MYSQL_ROW row;
            int i;
            unsigned int num_fields = mysql_num_fields(result);
    
            while ((row = mysql_fetch_row(result))) {
              for (i = 0; i < num_fields; i++) {
                printf("%s, ", row[i]);
              }
              putchar('\n');
            }
    
            mysql_free_result(result);
    	  }
    
      }  else {
    	  printf("Falha na pesquisa Error:%s\n",mysql_error(mycon));
      }
    }
    
    void captura_dados(PESSOAS *pes){
    	printf("Digite as informações que deseja pesquisar\n");
    	printf("==========================================\n");
    	printf("\nNome:");
    	scanf("%s",pes->nome);
    	printf("\n\n");
    }
    
    void Wellcome(void){
       printf("Software selPessoa\n");
       printf("Criado por Marcelo Maurin Martins\n");
       printf("Maurinsoft.com.br\n");
       //printf("Senha do banco:");
       //scanf("%s",PASS);
    }
    
    //funcao principal
    void main(int argc, char *argv[]){
       Wellcome();
       PESSOAS pessoa;
       /*Testa conexao*/
       if (conecta()==SUCCESS) {
          captura_dados(&pessoa);
          Select(&pessoa);
          desconecta();
       }
    }
    

    A primeira parte importante é a inclusão da lib, que permite compilar os comandos do mysql

    #include <mysql.h>

    Include da lib do mysql

    O outro ponto importante é a declaração mycon.

    MYSQL *mycon;

    variavel de conexão do mysq

    A mycon, é um handle do mysql. Que permite identificar a comunicação do banco aberta no comando mysql_init.

    mycon = mysql_init(NULL);

    inicia a comunicação com o mysql

    Atribuindo acesso ao banco.

    O comando mysql_real_connect atribui usuário e senha a conexão. Bem como estabelecendo um caminho entre o servidor correto.

    res = mysql_real_connect(
                  mycon,
                  HOST,
                  USER,
                  PASS,
                  DATABASE,
                  3306,
                  NULL,
                  0);

    São os principais parametros, HOST (o ip do servidor), user (usuário do banco), PASS(senha do banco), DATABASE (banco de dados), PORTA (default 3306).

    mysql_query

    O mysql_query permite rodar os comandos, tanto select, como update, delete e insert, ele é o mais importante comando.

    Para não falar em vídeozinho

    Segue a apresentação dos programas rodando.

    Referências

    https://dev.mysql.com/doc/c-api/8.0/en/

    https://zetcode.com/db/mysqlc/

    Artigos Relacionados

      Banco de dados C/C++ Delphi Lazarus Mysql PHP Python R
      Mysql com C/Lazarus/Python/PHP/R – Parte 1

      Neste super tutorial, iremos abordar a Conexão do Mysql com estas 5 linguagens.

      Na primeira parte do tutorial, iremos abordado o Mysql própriamente dita, onde faço a instalação e configuração.

      Nos próximos posts abordarei cada linguagem individualmente.

      Mysql

      Mysql é um banco fornecido pela Oracle, muito utilizado em aplicações embarcadas e web.

      De forma geral é um banco sólido, com uma ampla gama de aplicações, e seguro.

      Instalação no Linux / Ubuntu

      A instalação do servidor mysql é muito simples.

      apt install mysql-server

      Instalação do mysql server em Linux

      A instalação do Mysql é muito simples, e instala os principais componentes.

      Instalação do Mysql

      Vídeo de demonstração

      Instalação do Mysql

      Criando um banco de dados

      Agora, iremos criar um projeto de banco de dados bem simples.

      A idéia é basicamente permitir CRUD nos demais artigos. Para quem não conhece o CRUD, é a abreviação (Create, Read, Update, Delete).

      Para nos ajudar, irei criar um git, do projeto.

      Ambiente de desenvolvimento

      A instalação do ambiente de desenvolvimento precisa ser feito através da lib:

       apt-get install libmysqlclient-dev 

      A lib acima, instala os headers e .so para integração com C e outras linguagens, como Lazarus.

      A medida que avancemos nos demais artigos, irei incluindo aqui, as bibliotecas para as demais linguagens tambem. Então fique atento.

      GIT

      https://github.com/marcelomaurin/mysql-vs-todos

      SCRIPTS

      Agora iremos criar o Nosso Makefile para carregar os scripts:

      Arquivo Makefile

      # Script de criacao do banco de dados
      # Autor Marcelo Maurin Martins
      # Daa: 31/01/2022
      #
      
      
      APP=mysql
      
      all:  database Tabelas
      database:
      	$(APP)  < database.sql
      Tabelas:
      	$(APP) < pessoas.sql
      

      Em seguida iremos criar o script de criação da base de dados, database.sql:

      #Cria um banco de dados em Mysql
      #Autor: Marcelo Maurin Martins
      #31/01/2022
      
      
      create database IF NOT EXISTS `testedb`;

      E por fim nossa tabela pessoas.sql

      #Cria a tabela de pessoas
      #Autor: Marcelo Maurin Martins
      #31/01/2022
      
      use testedb;
      
      create table if not exists pessoas
      (
         idPessoa INT(6) unsigned auto_increment primary key,
         nome varchar(30) not null,
         dtnasc date,
         profissao varchar(20),
         sexo char(1),
         dtchg timestamp default current_timestamp on update current_timestamp,
         dtcad timestamp default current_timestamp
      );
      

      Executando Scripts

      Entre na pasta scripts, para que possamos criar nossas estruturas de banco.

      Digite o comando:

      make

      executa a criação do banco

      A figura abaixo mostra sua execução

      Exemplo do script do banco de dados

      Por fim mais um vídeozinho

      Procedimento de instalação dos scripts

      Permissões

      Ao montar o segundo artigo lembrei que para melhorar este artigo, o ideal seria criar uma conta especifica para cada aplicação. Desta forma criei um scripts novo chamado GRANTS.SQL

      Desta forma, existe essa ultima etapa. Que precisamos, que será criar um usuário para acesso a aplicação:

      Criando o usuario:

      CREATE USER 'seu_usuario'@'localhost' IDENTIFIED BY 'suasenha';

      Dando permissão:

      GRANT ALL PRIVILEGES ON * . * TO 'seu_usuario'@'localhost';

      Finalizando

      FLUSH PRIVILEGES;

      Este procedimento será validado, quando digitarmos

      mysql -h localhost -u gcc -p

      Conectando em banco de dados

      Pois se as permissões não estiverem corretas o usuario não conecta.

      Sempre que avançarmos em uma etapa, um novo usuário será criado, neste script.

      Então não estranhem se eventualmente os scripts sofrerem modificação no git.

      Cenas do próximos capítulos

      Agora que preparamos a cama, iremos começar a codificar nela. No próximo artigo iremos criar um crud em C para cadastrar pessoas.

      Até a próxima.

      Referências

      https://stackoverflow.com/questions/838978/how-to-check-if-mysql-database-exists

      https://stackoverflow.com/questions/11739014/how-to-generate-a-create-table-script-for-an-existing-table-in-phpmyadmin

      https://stackoverflow.com/questions/6239131/how-to-grant-remote-access-permissions-to-mysql-server-for-user

      https://linuxize.com/post/how-to-create-mysql-user-accounts-and-grant-privileges/

      Artigos Relacionados

        C/C++ IA pós graduação
        Introdução OpenGL

        Definição

        OpenGL é um conjunto de bibliotecas desenvolvidas para aplicação gráfica.

        Esta biblioteca contém um conjunto de funções que agrupam comandos de baixo nível. Permitindo criação de ambientes 2D e 3D.

        Entre as várias bibliotecas existentes podemos mencionar a GLU e a GLUT.

        GLU (OpenGL Utility Library) é instalada junto com o OpenGL, destinada principalmente para manipulação de matrizes complexas.

        GLUT (OpenGL Utility Toolkit) que é um pacote independente de plataforma, que inclui um conjunto de bibliotecas para interface gráfica.

        Instalando no linux

        Nosso foco aqui é 100% linux, por isso vou apresentar 2 formas de instalar no linux.

        Para instalar o OpenGL basta digitar o seguinte comando:

        apt install mesa-utils freeglut3-dev freeglut3 mesa-utils-extra

        Instalação do OpenGL

        A instalação seguiu conforme apresentado:

        Procedimento de instalação do OpenGL

        Vídeo mostrando o processo:

        Procedimento de instalação do OpenGL

        Localizando as libs em C

        Agora que instalamos as bibliotecas, temos que acha-las.

        Os include ficam localizados em

        /usr/include/GL

        Caminho dos includes para compilação em C

        Segue abaixo a contraprova de sua localização:

        Agora as libs ficam em

        /usr/lib/x86_64-linux-gnu/

        Conforme contraprova abaixo:

        Caminho instalado em um ubuntu

        Criando o Hello World

        Bom como é de costume, iremos criar o nosso primeiro programa.

        Não será muito inovador, mas tem a base para evoluirmos.

        GIT

        O código dele esta no git:

        https://github.com/marcelomaurin/opengl_hello

        Primeiro criaremos nosso fonte: hello.cpp

        
        #include <GL/glut.h>
        
        void displayMe(void)
        {
        	glClear(GL_COLOR_BUFFER_BIT);
                glBegin(GL_POLYGON);
                glVertex3d(0, 0, 0);
                glVertex3d(1, 0, 0);
                glVertex3d(1, 1, 0);
                glVertex3d(0, 1, 0);
                glEnd();
                glFlush();
        }
        
        
        int main(int argc, char** argv)
        {
        	glutInit(&argc, argv);
                glutInitDisplayMode(GLUT_SINGLE);
                glutInitWindowSize(300, 300);
                glutInitWindowPosition(100, 100);
                glutCreateWindow("Hello world");
                glutDisplayFunc(displayMe);
                glutMainLoop();
                return 0;
        }

        Agora iremos montar nosso arquivo de compilação: Makefile

        
        CC=g++
        
        SOURCE=hello.cpp
        BIN=hello
        
        LIBRARYS=-L/usr/lib/x86_64-linux-gnu/ -lglut -lGLU -lm -lGL
        
        all: clean compile
        
        clean:
        
        compile:
        	$(CC) $(SOURCE) -o $(BIN) $(LIBRARYS)
        

        E para completar a festa a imagem gerada e em seguida o vídeo apresentando:

        Imagem de um quadrado 2D, gerado por OpenGL

        Vídeo no Youtube

        Vídeo de apresentação do OpenGL sendo compilado em Linux.

        Referências

        https://www.opengl.org/

        https://askubuntu.com/questions/96087/how-to-install-opengl-glut-libraries

        OpenGL – Uma Abordagem Prática e Objetiva – Marcelo Cohen , Isabel Hard Manssour

        Blog C/C++ IA OPENCV OpenCV pós graduação Python
        OpenCV em C

        Em um artigo anterior fiz um exemplo de opencv em Python.

        OpenCV em Python

        Neste artigo irei apresentar um exemplo de código de opencv em C++.

        Irei comentar traçando referencias entre o código do C e o código do python.

        O Exemplo utililizado será fornecido pela própria biblioteca em python.

        Aqui vemos o exemplo comentado do fonte

        OpenCV em Python

        Para traçar um paralelo usaremos os códigos do opencv, o programa chamado video_v4l2.py

        Conforme apresentado abaixo:

        #!/usr/bin/env python
        
        '''
        VideoCapture sample showcasing  some features of the Video4Linux2 backend
        
        Sample shows how VideoCapture class can be used to control parameters
        of a webcam such as focus or framerate.
        Also the sample provides an example how to access raw images delivered
        by the hardware to get a grayscale image in a very efficient fashion.
        
        Keys:
            ESC    - exit
            g      - toggle optimized grayscale conversion
        
        '''
        
        # Python 2/3 compatibility
        from __future__ import print_function
        
        import numpy as np
        import cv2 as cv
        
        def main():
        
            def decode_fourcc(v):
                v = int(v)
                return "".join([chr((v >> 8 * i) & 0xFF) for i in range(4)])
        
            font = cv.FONT_HERSHEY_SIMPLEX
            color = (0, 255, 0)
        
            cap = cv.VideoCapture(0)
            cap.set(cv.CAP_PROP_AUTOFOCUS, 0)  # Known bug: https://github.com/opencv/opencv/pull/5474
        
            cv.namedWindow("Video")
        
            convert_rgb = True
            fps = int(cap.get(cv.CAP_PROP_FPS))
            focus = int(min(cap.get(cv.CAP_PROP_FOCUS) * 100, 2**31-1))  # ceil focus to C_LONG as Python3 int can go to +inf
        
            cv.createTrackbar("FPS", "Video", fps, 30, lambda v: cap.set(cv.CAP_PROP_FPS, v))
            cv.createTrackbar("Focus", "Video", focus, 100, lambda v: cap.set(cv.CAP_PROP_FOCUS, v / 100))
        
            while True:
                _status, img = cap.read()
        
                fourcc = decode_fourcc(cap.get(cv.CAP_PROP_FOURCC))
        
                fps = cap.get(cv.CAP_PROP_FPS)
        
                if not bool(cap.get(cv.CAP_PROP_CONVERT_RGB)):
                    if fourcc == "MJPG":
                        img = cv.imdecode(img, cv.IMREAD_GRAYSCALE)
                    elif fourcc == "YUYV":
                        img = cv.cvtColor(img, cv.COLOR_YUV2GRAY_YUYV)
                    else:
                        print("unsupported format")
                        break
        
                cv.putText(img, "Mode: {}".format(fourcc), (15, 40), font, 1.0, color)
                cv.putText(img, "FPS: {}".format(fps), (15, 80), font, 1.0, color)
                cv.imshow("Video", img)
        
                k = cv.waitKey(1)
        
                if k == 27:
                    break
                elif k == ord('g'):
                    convert_rgb = not convert_rgb
                    cap.set(cv.CAP_PROP_CONVERT_RGB, 1 if convert_rgb else 0)
        
            print('Done')
        
        
        if __name__ == '__main__':
            print(__doc__)
            main()
            cv.destroyAllWindows()
        

        A primeira informação importante é a carga das bibliotecas do opencv em python.

        import cv2 as cvimport cv2 as cv

        carga da lib em python

        O proximo ponto importante é onde capturamos o vídeo.

        cap = cv.VideoCapture(0)

        Captura do vídeo

        O Parametro 0, indica que o device de vídeo é o padrão do sistema.

        O ponto importante no código é o uso do cap, no código abaixo:

        _status, img = cap.read()

        captura do frame

        Ao chamar a função read, dois parametros são retornados, _status (retorno de sucesso) e img, a imagem capturada.

        Por fim, uma janela é montada com a visualização da imagem capturada:

        cv.imshow(“Video”, img)

        janela é montada

        Agora iremos analisar o mesmo código em C.

        OpenCV em C

        Agora mostraremos o código em C, o exemplo é o videocapture_basic.cpp:

        
        #include <opencv2/core.hpp>
        #include <opencv2/videoio.hpp>
        #include <opencv2/highgui.hpp>
        #include <iostream>
        #include <stdio.h>
        
        using namespace cv;
        using namespace std;
        
        int main(int, char**)
        {
            Mat frame;
            //--- INITIALIZE VIDEOCAPTURE
            VideoCapture cap;
            // open the default camera using default API
            // cap.open(0);
            // OR advance usage: select any API backend
            int deviceID = 0;             // 0 = open default camera
            int apiID = cv::CAP_ANY;      // 0 = autodetect default API
            // open selected camera using selected API
            cap.open(deviceID, apiID);
            // check if we succeeded
            if (!cap.isOpened()) {
                cerr << "ERROR! Unable to open camera\n";
                return -1;
            }
        
            //--- GRAB AND WRITE LOOP
            cout << "Start grabbing" << endl
                << "Press any key to terminate" << endl;
            for (;;)
            {
                // wait for a new frame from camera and store it into 'frame'
                cap.read(frame);
                // check if we succeeded
                if (frame.empty()) {
                    cerr << "ERROR! blank frame grabbed\n";
                    break;
                }
                // show live and wait for a key with timeout long enough to show images
                imshow("Live", frame);
                if (waitKey(5) >= 0)
                    break;
            }
            // the camera will be deinitialized automatically in VideoCapture destructor
            return 0;
        }
        

        O primeiro ponto assim como no código em python, e a chamada da biblioteca em c.

        #include <opencv2/core.hpp>
        #include <opencv2/videoio.hpp>
        #include <opencv2/highgui.hpp>

        Sem esses includes não teriamos acessos aos tipos do C, como o que segue:

        VideoCapture cap;

        O tipo VideoCapture é o tipo associado a captura de vídeo da câmera.

        Onde usaremos, conforme fragmento abaixo:

        int deviceID = 0;             // 0 = open default camera
        int apiID = cv::CAP_ANY;      // 0 = autodetect default API
        // open selected camera using selected API
        cap.open(deviceID, apiID);

        Aqui, definimos o deviceID como 0, ou seja, o valor padrão, veja a semelhança do uso do python.

        E apiID, passando o escopo (variavel) CAP_ANY, que tem por valor 0.

        Chamamos o método open da classe VideoCapture, indicando o deviceID, e o apiID.

        Agora iremos ler a imagem da camera, que podemos fazer, através da seguinte função:

        cap.read(frame);

        Neste fragmento de código, passamos o parametro frame, que é do tipo Mat.

        O frame receberá a imagem capturada.

        E por fim, no código abaixo a janela que irá mostrar a imagem na interface gráfica.

        imshow("Live", frame);

        Conclusão

        Apesar das diferenças de linguagem, podemos ver o pontos em comum, e a sutileza da semelhança.

        É lógico que os códigos foram escolhidos a dedo. Justamente por conta da semelhança e simplicidade.

        O opencv é uma biblioteca rica, cheia de opções e dificuldades, este tutorial, bem como o autor, esta apenas adentrando neste mundo para mim misterioso.

        Espero que tenham gostado deste artigo. 😉

        RFID
        RFID com gravação de parametros pela eeprom

        A partir da versão 1.0.3, os parametros serão gravados na EEPROM.

        Esta mudança visa retirar a dependencia do pino 4.

        Agora a parametrização é feita por comandos na serial usando o putty são gravados na memória não volátil do firmware.

        Novos parametros foram adicionados a versão 1.0.3

        • Modo Debug
        • Modo HEX Decimal
        • Modo ECHO
        • Modo TECLADO
        • Modo SERIAL

        São parametros que podem ser ativados ou inativados.

        Com o ajuste de parametrização pela serial, tambem é possivel ler o ultimo cartão lido.

        O detalhamento, bem como as informações dos comandos completos, estarão disponíveis em documentação neste site.

        Blog RFID
        A importancia da prototipagem

        A prototipagem é a capacidade de transformar idéias em algo real, criando uma ou mais exemplares a fim de teste de conceito.

        A prototipagem não visa criar um produto final, mas validar o conceito deste. Realizando testes de viabilidade, resistência e usabilidade.

        O protótipo pode ser modificado e amadurecido, durante o seu tempo de teste. Podendo passar por muitas revisões. Sendo de fato, um tempo destinado para este amadurecimento como produto.

        A prototipagem de hardware pode ser:

        Prototipagem eletrônica – Consistindo em partes impressas ou não, montadas de forma artesanal ou em cnc routers especificos para PCB. Com o intuíto de teste de circuitos eletrônicos.

        Prototipagem mecânica – Consiste em partes impressas ou não , montadas de forma artesanal ou em impressoras 3d.

        Um exemplo de prototipagem é a construção da caixa do RFID, que na revisão 1, identificou um erro no posicionamento do chanfro.

        Conforme vídeo abaixo:

        Erro de prototipagem da caixa plastica.

        No caso deste projeto houve duas ações.

        Correção da caixa, através uma broca foi feito o ajuste grosseiro na mesma.

        Correção no projeto, através de ferramenta cad, a correção no projeto da caixa, para reimpressão e ajuste.

        en_USEnglish