Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/israel-nogueira/galaxy-db

Conheça o GalaxyDB, uma classe simples e completa para desenvolvimento e gerenciamento de base de dados em PHP. Experimente e ajude esse projeto a melhorar.
https://github.com/israel-nogueira/galaxy-db

database-management mariadb-database mariadb-mysql mongodb mongodb-database mysql mysql-database orm orm-framework postgrid

Last synced: 9 days ago
JSON representation

Conheça o GalaxyDB, uma classe simples e completa para desenvolvimento e gerenciamento de base de dados em PHP. Experimente e ajude esse projeto a melhorar.

Awesome Lists containing this project

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.

```plaintext
composer require israel-nogueira/galaxy-db
```

Acrescente em seu _composer.json_:

```plaintext
"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 base
- `pass`: Senha
- `name`: Nome da base
- `host ` Porta

Caso falte algum ou todos os dados, o prompt irá lhe pedir.

```plaintext

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

#/.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:
```plaintext

composer run-script galaxy update-snippets

```

E Pronto, você e seu VSCode estão prontos para trabalhar de maneira rápida e eficaz.
![GalaxyDB](https://raw.githubusercontent.com/israel-nogueira/galaxy-db/main/src/snippets-exemplo.gif)

#### 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:

```plaintext
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

```

A _Model_ é o uso da classe abstrata da classe principal.
Nela serão cadastrados os parâmetros de uso da classe.

```php

```

## 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

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:

```sql
SELECT nome,email as mail,endereco,telefone FROM usuarios WHERE id=7
```

### Select mais completo

```php
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:

```sql
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
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:

```sql
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
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');

?>
```

```sql
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
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:

```json
{
"users_1":[
{
"username": "username_01",
"email": "[email protected]"
}
],
"valores":[
{
"VALOR": "100.00"
}
]
}
```

## Insert

Podemos inserir dados de algumas formas diferentes:

```php
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

```php

// 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

```php

//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:

```php

$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
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
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
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
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
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

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
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
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
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:

```json
{
"processaDados":{
"@_NOME":"João da Silva",
"@_EMAIL":"[email protected]",
},
"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
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:
```json

{
"LISTA_PRODUTOS" : [
{
"id": 654,
"nome": "cadeira de madeira",
"valor": 21.5,
},
{
"id": 655,
"nome": "Mesa de plástico",
"valor": 149.9,
}
]
}
```

$_OUTPUT:
```json
{
"processaDados":{
"@_NOME":"João da Silva",
"@_EMAIL":"[email protected]",
},
"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```;

```env

# /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
NOME = 'João da Silva';
$users->isCrypt()->CPF = '947.029.456-67';
$users->isCrypt()->EMAIL = '[email protected]';
$users->isCrypt()->PIN = '3659';
$users->insert();

?>
```
Em sua base ficará assim:

| NOME | CPF | EMAIL | PIN
|--|--|--|--|
| João da Silva | NCUB1pM9/orreKyzctvaVg== | wOvOZFR1hItpTWiwa4m3ntak= | a45EqjRSU0RRrmTEFQifvA== |

E quando for receber esse valor, sete novamente a flag.

```php
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:
```plaintext
$ composer run-script galaxy enable-rac
```

Para desativar serviço:
```plaintext
$ composer run-script galaxy disable-rac
```

Você também pode executar programaticamente em PHP:
```php
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ção
- ``ACTION``: INSERT | UPDATE | DELETE
- ``QUERY``: Query que foi executada
- ``ROLLBACK``: Query "ctrl+z", voltará ao estado anterior da ação executada
- ``DATA_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

```sql

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:
```plaintext

composer run-script galaxy new-migration

```

Você também pode executar programaticamente em PHP:
```php
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```;

```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`;

```