israel-nogueira / galaxy-db
ORM simples para PHP e Base de Dados
Requires
- php: >=7.4
README
Instalação |
Config a base |
Snippets |
Models |
Exemplos de uso
Functions |
Crypt |
Store Procedures |
RAC |
Migrations
Classe para controlar a sua base de dados no PHP com facilidade e segurança.
Essa classe dá suporte as seguintes conexões:
mysql
pgsql
sqlite
ibase
fbird
oracle
mssql
dblib
sqlsrv
Instalação
Instale via composer.
composer require israel-nogueira/galaxy-db
Acrescente em seu composer.json:
"scripts": {
"galaxy": "php vendor/israel-nogueira/galaxy-db/src/galaxy"
}
GUIA PRÁTICO
CONFIGURANDO A BASE
Você pode configuraros dados de conexão via CLI:
type
: Sigla do tipo de base (mysql, pgsql etc)user
: Usuário da basepass
: Senhaname
: Nome da basehost
Porta
Caso falte algum ou todos os dados, o prompt irá lhe pedir.
composer run-script galaxy config-connection -- --type= --user= --pass= --name= --host=
Ou criar manualmente um arquivo /.env
na raiz do seu projeto e preencha os dados de conexão de sua base:
#/.env DB_HOST=localhost DB_PORT=3306 DB_DATABASE=MyDataBase DB_TYPE=mysql DB_USERNAME=root DB_PASSWORD= DB_CHAR= DB_FLOW= DB_FKEY=
Snippets para VSCode
Depois que você configurou os dados de conexão, poderá criar um snippets da classe.
Sim, essa classe também conta com um script que importa a estrutura da sua base de dados.
E monta um snippets com atalhos.
Para criar ou atualizar seu snippets, basta executar:
composer run-script galaxy update-snippets
E Pronto, você e seu VSCode estão prontos para trabalhar de maneira rápida e eficaz.
Alguns atalhos:
select
, update
, insert
ou delete
retornam a classe completa de CRUD;
table
ou ->table
:
Mostra a lista de tabelas disponíveis em sua base de dados;
Se tiver ->
retorna a função montada ->table("sua-tabela")
;
Caso contrario, retorna apenas o nome da tabela
colum
ou ->colum
:
Se tiver ->
retorna a função montada ->colum("sua-tabela")
;
Caso contrario, retorna apenas o nome da coluna.
Inicialmente ela mostra a lista de tabelas disponíveis em sua base de dados;
E na sequencia a lista de colunas daquela tabela selecionada.
columns
ou tables
:
Você pode retornar uma lista de tabelas ou colunas de sua base de dados
columns
ou tables
:
Você pode retornar uma lista de tabelas ou colunas de sua base de dados
E com tempo vamos incrementando a lista de atalhos.
CRIANDO MODELS
Este é o comando para criar suas Models.
Cada palavra é um parametro, por exemplo “usuarios e produtos” no comando:
composer run-script galaxy new-model usuarios produtos
Isso criará automaticamente os seguinte arquivos:
/app/models/usuariosModel.php
/app/models/produtosModel.php
PADRÃO DAS MODELS
Basta importar o autoload e o namespace da sua Model e utilizar
<?php include "vendor\autoload.php"; use IsraelNogueira\Models\usuariosModel; ?>
A Model é o uso da classe abstrata da classe principal.
Nela serão cadastrados os parâmetros de uso da classe.
<?php namespace IsraelNogueira\Models; use IsraelNogueira\galaxyDB\galaxyDB; class usuariosModel extends galaxyDB { // TABELA PADRÃO protected $table = 'usuarios'; // COLUNAS BLOQUEADAS protected $columnsBlocked = []; // COLUNAS PERMITIDAS protected $columnsEnabled = []; // FUNÇÕES MYSQL PROIBIDAS protected $functionsBlocked = []; // FUNÇÕES MYSQL PERMITIDAS protected $functionsEnabled = []; } ?>
EXEMPLOS DE USO
Select simples
O exemplo apresenta um SELECT
básico com um filtro apenas para usuário com ID=7
.
Uma array
vazia será retornada caso a consulta não encontre resultados.
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $users = new usuariosModel(); $users->colum('nome');//unitario $users->colum('email as mail');// com alias $users->colum(['endereco','telefone']); // ou ainda varias de uma vez $users->set_where('id=7'); $users->select(); $_RESULT = $users->fetch_array(); // retorna um ARRAY ?>
Resultará no seguinte select:
SELECT nome,email as mail,endereco,telefone FROM usuarios WHERE id=7
Select mais completo
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $users = new usuariosModel(); $users->colum('nome'); $users->colum('bairro_id'); $users->join('INNER','bairros',' bairros.id=usuarios.bairro_id') ->join('LEFT','cidades',' cidades.id=usuarios.cidade_id'); // TIPO | TABELA | ON $users->group_by('bairros'); // GROUP BY $users->like('nome','%edro%')->like('nome','%ão%'); $users->order('nome','asc')->order('idade','desc'); // ORDER BY nome ASC, idade DESC $users->limit(1,10); // SET LIMIT 1, 10 $users->where('cidades.id=11'); $users->distinct(); // ignora os resultados repetidos $users->debug(true); // false não retornará erros e falhas. Default:true $users->select(); // $_ARRAY[0]["nome"] | $_ARRAY[1]["nome"] $_ARRAY = $users->fetch_array(); // $_OBJECT[0]->nome | $_OBJECT[1]->nome $_OBJECT = $users->fetch_obj(); ?>
Resultará em uma query assim:
SELECT DISTINCT nome, bairro_id FROM usuarios INNER JOIN bairros ON bairros.id = usuarios.bairro_id LEFT JOIN cidades ON cidades.id = usuarios.cidade_id WHERE ( cidades.id = 11 AND ( Lower(nome) LIKE Lower("%edro%") OR Lower(nome) LIKE Lower("%ão%") ) ) GROUP BY bairros ORDER BY nome ASC, idade DESC
SUB SELECTS
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $users = new usuariosModel(); // Puxamos todos usuarios que morem na cidade 11 ( 11=Curitiba ) // Criamos um sub select e instanciamos como "cidade_11" $users->set_where('cidade_id=11'); $users->setSubQuery('cidade_11'); // Agora selecionamos com o tableSubQuery() nossa subQuery e damos o alias de "curitiba" $users->tableSubQuery('(cidade_11) curitiba'); $users->set_where('curitiba.solteiros=1'); // Poderiamos parar poraqui mas se quiser aprofundarmos $users->setSubQuery('solteiros'); $users->tableSubQuery('(solteiros) sexo'); $users->set_where('solteiros.sexo="male"'); // Executamos o select puxando os moradores da cidade 11 // e depois filtramos os solteiros $users->select('homens_solteiros_curitiba'); $_ARRAY = $users->fetch_array('homens_solteiros_curitiba'); ?>
Isso resultará na seguinte query:
SELECT * FROM (SELECT * FROM (SELECT * FROM usuarios WHERE ( cidade_id = 11 )) curitiba WHERE ( curitiba.solteiros = 1 )) sexo WHERE ( solteiros.sexo = "male" )
Também podemos aplicar uma subquery a uma coluna:
<?php include "vendor\autoload.php"; use App\Models\meusUsuario; $users = new usuariosModel(); // Aqui apenas trazemos o total de usuarios que moram na cidade 11 $users->colum('COUNT(1) as total_registro '); $users->set_where('cidade_id=11'); $users->setSubQuery('total_11'); // <----- Cria subquery "total_11" $users->colum('user.*'); $users->columSubQuery('(total_11) AS total_curitibanos'); // Monta coluna com a Subquery $users->set_where('total_curitibanos>100'); $users->prepare_select('homens_solteiros_curitiba'); $_ARRAY = $users->fetch_array('homens_solteiros_curitiba'); ?>
SELECT user.*, ( SELECT COUNT(1) AS total_registro FROM users WHERE(cidade_id=11) ) AS total_curitibanos FROM users WHERE ( total_curitibanos > 100 )
MULTIPLOS SELECTS
Podemos também executar múltiplos selects em uma só instancia:
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $users = new usuariosModel(); $users->colum('username'); $users->colum('email'); $users->limit(1); $users->prepare_select('users_1'); //Guardamos a query $users->table('financeiro__historico'); // pode setar uma nova tabela $users->colum('VALOR'); $users->limit(1); $users->where('PAGADOR="'.$uid.'"'); $users->prepare_select('valores');//Guardamos a query // executamos todas as querys $getInfoBanner->execQuery(function($galaxy){}); $_ARRAY = $users->fetch_array(); ?>
Nos resultará no seguinte array:
{ "users_1":[ { "username": "username_01", "email": "exemplo@email.com" } ], "valores":[ { "VALOR": "100.00" } ] }
Insert
Podemos inserir dados de algumas formas diferentes:
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; //FORMA SIMPLIFICADA $users = new usuariosModel(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->insert(); //Todas as condicionais podem ser aplicadas aqui também $users = new usuariosModel(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->where('NOW() > "00-00-00 00:00:00"'); $users->insert(); ?>
MULTIPLOS INSERTS + TRANSACTION + ROLLBACK
<? // MULTIPLOS INSERTS $users = new usuariosModel(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->prepare_insert(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->where('NOW() > "00-00-00 00:00:00"'); $users->prepare_insert(); // TRANSACTION + ROLLBACK $users->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); //EXECUTA OS INSERTS $users->execQuery(function($galaxy){}); ?>
INSERT ARRAY + TRANSACTION + ROLLBACK
<? //PUXANDO UMA ARRAY $users = new usuariosModel(); $users->set_insert_obj(['UID'=>32,'NOME'=>'João', 'IDADE'=>27]); $users->prepare_insert(); //DENTRO DE UM LAÇO foreach($_RESULTADO as $OBJ){ $users->set_insert_obj($OBJ); $users->prepare_insert(); } // TRANSACTION + ROLLBACK $users->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); //EXECUTA OS INSERTS $users->execQuery(function($galaxy){}); ?>
CALLBACKS
Para termos um callback de sucesso ou erro basta inserir:
<? $users = new galaxyDB(); $users->connect(); $users->table('usuarios'); $users->UID = 3456; $users->NOME='João'; $users->IDADE=27; $users->prepare_insert('adiciona_user'); $users->transaction(function ($ERROR) { // Callback de erro! // Aqui o $ERROR, é o proprio retorno do MySQL throw new ErrorException($ERROR, 1); }); $users->execQuery(function($galaxy){ // Callback de sucesso! // Aqui o $galaxy, é o proprio objeto da classe // que no caso é $users die(var_dump($galaxy->_last_id)); }); ?>
UPDATE:
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; //FORMA SIMPLIFICADA $users = new usuariosModel(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->update(); //Todas as condicionais podem ser aplicadas aqui também $users = new usuariosModel(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->where('UID="7365823765"'); $users->update(); ?>
MULTIPLOS UPDATES + TRANSACTION + ROLLBACK:
<?php // MULTIPLOS UPDATES $users = new usuariosModel(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->where('UID="46746876"'); $users->prepare_update(); $users->coluna1 = 'valor'; $users->coluna2 = 'valor'; $users->coluna3 = 'valor'; $users->where('UID="9653566573"'); $users->prepare_update(); // TRANSACTION + ROLLBACK $users->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); //EXECUTA OS UPDATES $users->execQuery(function($galaxy){}); ?>
MULTIPLOS UPDATES COM ARRAYS:
<?php //PUXANDO UMA ARRAY $users = new usuariosModel(); $users->set_update_obj(['UID'=>32,'NOME'=>'João', 'IDADE'=>27]); $users->prepare_update(); //DENTRO DE UM LAÇO foreach($_RESULTADO as $OBJ){ $users->set_update_obj($OBJ); $users->prepare_update(); } // TRANSACTION + ROLLBACK $users->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); //EXECUTA OS INSERTS $users->execQuery(function($galaxy){}); ?>
DELETE
<?php //DELETE DIRETO E SIMPLES $users = new usuariosModel(); $users->where('UID=32'); $users->delete(); //PREPARANDO MULTIPLOS $users = new usuariosModel(); $users->where('UID=32'); $users->prepare_delete();//Armazena //DENTRO DE UM LAÇO foreach($_RESULTADO as $OBJ){ $users->where('UID='.$OBJ['UID']); $users->prepare_delete();//Armazena } // TRANSACTION + ROLLBACK $users->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); //EXECUTA OS DELETES $users->execQuery(function($galaxy){}); ?>
FUNÇÕES NA MODEL
Você pode também estender padrões em sua model.
Podendo abstrair mais nossas consultas.
Seguindo o exemplo abaixo:
<?php namespace IsraelNogueira\Models; use IsraelNogueira\galaxyDB\galaxyDB; class usuariosModel extends galaxyDB { protected $table= 'usuarios'; // AQUI MONTAMOS A NOSSA FUNÇÃO ESTENDIDA public function cidadeEstado(){ $this->colum('city.nome as cidade'); $this->colum('uf.nome as uf'); $this->join('LEFT','table_cidade cidade','cidade.id=usuarios.cidade_id'); $this->join('LEFT','table_uf uf','uf.id=cidade.uf_id'); } } ?>
E quando for utilizar a classe:
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $users = new usuariosModel(); $users->colum('nome'); $users->colum('idade'); $users->cidadeEstado(); //====> aqui executamos nossa função $users->select(); $_RESULT = $users->fetch_array(); ?>
STORED PROCEDURES
Uma Store Procedure, pode ser chamada de duas maneiras.
1ª - Função ->SP()
$usuarios->sp( NOME_DA_SP, ARRAY_PARAMS );
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $usuarios = new usuariosModel(); $usuarios->sp("processaDados",['PARAM0','PARAM1','PARAM2']); $usuarios->prepare_sp(); $usuarios->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); $usuarios->execQuery(function($galaxy){}); $_RESULT = $users->fetch_array(); ?>
2ª - FUNÇÃO MÁGICA
Você também pode chamar simplesmente adicionando sp_
na frente da sua função,
que a classe automaticamente entende que essa função é uma Stored Procedure;
Exemplo:
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $usuarios = new usuariosModel(); $teste->sp_processaDados('PARAM0','PARAM1','PARAM2'); $teste->sp_sobePontos('PARAM0','PARAM1','PARAM2'); $teste->prepare_sp(); $teste->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); $teste->execQuery(function($galaxy){}); ?>
PARÂMTROS IN OUT
Todo parâmetro que você inserir com @
no início,
a classe identifica que é um parâmetro de saída.
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $usuarios = new usuariosModel(); $teste->sp_processaDados('PARAM0','@_NOME','@_EMAIL',25); $teste->sp_sobePontos(637,'@_NOME'); $teste->prepare_sp(); $teste->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); $teste->execQuery(function($galaxy){}); $_RESULT = $teste->params_sp(); ?>
A variável $_RESULT
representará a seguinte saída:
{ "processaDados":{ "@_NOME":"João da Silva", "@_EMAIL":"joao@gmail.com", }, "sobePontos":{ "@_NOME2":"João da Silva" } }
PARÂMTROS IN OUT MAIS SELECTS
Caso a sua Store Procedure possúa algum select interno, será processado como uma query;
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $usuarios = new usuariosModel(); $usuarios->table("produtos"); $usuarios->limit(1); $usuarios->prepare_select("LISTA_PRODUTOS"); $usuarios->sp_processaDados('PARAM0','@_NOME','@_EMAIL',25); $usuarios->sp_sobePontos(637,'@_NOME'); $usuarios->prepare_sp(); $usuarios->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); $usuarios->execQuery(function($galaxy){}); $_RESULT = $usuarios->fetch_array(); $_OUTPUT = $usuarios->params_sp(); ?>
Resultará em:
$_RESULT:
{ "LISTA_PRODUTOS" : [ { "id": 654, "nome": "cadeira de madeira", "valor": 21.5, }, { "id": 655, "nome": "Mesa de plástico", "valor": 149.9, } ] }
$_OUTPUT:
{ "processaDados":{ "@_NOME":"João da Silva", "@_EMAIL":"joao@gmail.com", }, "sobePontos":{ "@_NOME2":"João da Silva" } }
CRIPTOGRAFIA
Para utilizar essa funcionalidade, será necessário inserir dois parametros no arquivo /.env:
GALAXY_CRYPT_KEY
e GALAXY_CRYPT_IV
;
# /var/www/.env # Uma chave forte GALAXY_CRYPT_KEY= # 16 caracteres GALAXY_CRYPT_IV=
Para mais detalhes, leia a documentação do PHP:
https://www.php.net/manual/en/function.openssl-encrypt
https://www.php.net/manual/en/function.openssl-decrypt
Digamos que você tenha algum dado sensível em sua base,
e não gostaria de deixar ela solta em meio a outros dados em suas tabelas;
Você poderá utilizar o método isCrypt()
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $users = new usuariosModel(); $users->NOME = 'João da Silva'; $users->isCrypt()->CPF = '947.029.456-67'; $users->isCrypt()->EMAIL = 'email@secret.com'; $users->isCrypt()->PIN = '3659'; $users->insert(); ?>
Em sua base ficará assim:
E quando for receber esse valor, sete novamente a flag.
<?php include "vendor\autoload.php"; use App\Models\usuariosModel; $users = new usuariosModel(); $users->colum('NOME'); $users->isCrypt()->colum('CPF'); $users->isCrypt()->colum('EMAIL'); $users->isCrypt()->colum('PIN'); $users->prepare_select('usuarios'); $users->transaction(function ($ERROR) { throw new ErrorException($ERROR, 1); // erro }); $users->execQuery(function($galaxy){}); ?>
RAC - REGISTRO DE ALTERAÇÕES DE CONTEÚDO
O GalaxyDB possui um mecanismo integrado de registro de alterações de conteúdo que permite rastrear e visualizar todas as modificações feitas nos dados do conteúdo. Esse recurso permite uma gestão mais eficiente e um histórico completo das alterações realizadas, facilitando a auditoria e o controle de versões.
Para ativar serviço:
$ composer run-script galaxy enable-rac
Para desativar serviço:
$ composer run-script galaxy disable-rac
Você também pode executar programaticamente em PHP:
<?php include "vendor\autoload.php"; use IsraelNogueira\galaxyDB\galaxyDB; // ATIVA SERVIÇO $_SELECT = new galaxyDB(); $_SELECT->connect(); $_SELECT->enableRAC(); // DESATIVA SERVIÇO $_SELECT = new galaxyDB(); $_SELECT->connect(); $_SELECT->disableRAC(); ?>
Isso criará uma tabela em sua base chamada GALAXY__RAC
onde será inserido 5 colunas:
TABELA
: Tabela que foi feita a açãoACTION
: INSERT | UPDATE | DELETEQUERY
: Query que foi executadaROLLBACK
: Query "ctrl+z", voltará ao estado anterior da ação executadaDATA_HORA
: Data e hora que foi executado o comando
MIGRATIONS
O GalaxyDB também possúi um sistema de migration próprio;
Isso quer dizer que todas as alterações estruturais feitas na base de dados,
como criação/alterações/exclusões de TABELAS
,COLUNAS
, TRIGGERS
ou STORE PROCEDURES
.
Atenção:
Para que essas funções funcionem, é necessário antes executar esse comando em seu MySQL;
Obs.: Coloque o PATH do seu arquivo da sua preferencia
SET GLOBAL general_log = 'ON'; SET GLOBAL general_log_file="/var/www/html/galaxyDB/galaxy.log";
EXECUTANDO
Pronto! Agora que estamos configurados, você pode criar umas tabelas,
editar umas colunas, criar algumas triggers e execute o comando:
CLI:
composer run-script galaxy new-migration
Você também pode executar programaticamente em PHP:
<?php include "vendor\autoload.php"; use IsraelNogueira\galaxyDB\galaxyDB; $_SELECT = new galaxyDB(); $_SELECT->connect(); $_SELECT->setHistorySQLfile(); ?>
Agora você poderá verificar que foi criado um arquivo na raiz do sistema:
/galaxyDB/{DB_DATABASE}_{d-m-Y-H-i-s}.sql
;
CREATE TABLE `DBNAME`.`NOVA_TABELA` (`ID` INT NOT NULL AUTO_INCREMENT , `COLUNA1` VARCHAR(123) NOT NULL, `COLUNA2` INT(11) NOT NULL , PRIMARY KEY (`ID`)) ENGINE = InnoDB; ALTER TABLE `NOVA_TABELA` DROP `COLUNA1`; ALTER TABLE `NOVA_TABELA` DROP `COLUNA2`;