Symfony2 + Sublime Text 2 - Limpando a casa

Published on:

O Symfony2 gera vários arquivos de cache para acelerar a execução do código, mas estes arquivos atrapalham a navegação no código. Aqui está uma simples dica de como deixar seu ambiente mais limpo.

Abra o seu projeto e vá em Project –> Edit Project e use esta configuração. Lembre-se de ajustar o path para o caminho do seu projeto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
  "folders":
  [
      {
          "name": "app",
          "path": "/Users/robinho/Sites/symfony.robinho",
          "file_exclude_patterns":
          [
              "composer.phar",
              "app/bootstrap.php.cache",
              // O Doctrine cria backup das Entities adicionando '~' ao final do arquivo.
              "*~"
          ],
          "folder_exclude_patterns":
          [
              // Arquivos de cache gerado pelo Symfony2.
              "app/cache",
              // Forçar a indexação dos assets na pasta dos bundles. Evita duplicado
              // Muito útil para que comandos como SVN FILE DIFF funcione corretamente.
              "web/bundles",
              // Separando o VENDOR da aplicação
              "vendor"
          ]
      },
      {
          // Colocando o VENDOR em outra pasta
          "path": "/Users/robinho/Sites/symfony.robinho/vendor",
          "name": "vendor"
      }
  ]
}

Instalando o CyanogenMod no Motorola Xoom MZ601

Published on:

Recentemente comprei um Motorola XOOM MZ601 usado, e como bom NERD que sou, arrumei logo um jeito de instalar o CyanogenMod nele. Sem muita enrolação, lá vai um tutorial simples de como instalar o CyanogenMod no Motorola XOOM MZ601.

OBS.: Este procedimento pode causar danos ao seu tablet e a perda da garantia.

OBS 2.: Leia todo o tutorial antes de fazer qualquer coisa.

Pré-Requisitos

Recomendo colocar os binários do Android SDK Tools na variável PATH do sistema operacional.

Obs.: No momento que o tutorial foi escrito usei a versão 10 do CyanogenMod, 20121011 do Google Apps e 6.0.2.9 do ClockworkMod Recovery.

Instalação

Desbloqueando o tablet

Com o tablet conectado ao computador pelo USB, abra o terminal e execute os comandos:

1
2
adb reboot bootloader
fastboot oem unlock

Siga todas as instruções que aparecerão na tela do tablet.

Copiando os arquivos necessários

Depois de desbloquear o tablet ele irá restaurar as condições de fábrica e reiniciará. Lembre de habilitar novamente o modo “Depuração USB”.

Ainda conectado ao Computador pelo USB, execute:

1
2
adb push cm-10.0.0-everest.zip /sdcard
adb push gapps-jb-20121011-signed.zip /sdcard

Instalando o Recovery

Após copiar todos os arquivos necessários para instalar a ROM, vamos instalar o Recovery. Continue com o USB conectado e execute os comandos:

1
2
adb reboot bootloader
fastboot flash recovery recovery-clockwork-6.0.2.9-stingray.img

Agora que o aparelho está desbloqueado e com o Recovery instalado, é só instalar a ROM e ser feliz.

Instalando a ROM

Desligue o tablet e religue-o segurando o botão de Ligar e o botão de volume para cima ao mesmo tempo. Assim que aparecer o mascote do Android, solte todos os botões. Três segundos após ter visto o mascote, aperte o botão volume para baixo. Aparecerá no canto superior esquerdo a opção “—> Android Recovery”. Aperte o volume para cima para que ele entre no ClockworkMod Recovery.

No ClockworkMod Recovery, faça um “wipe data/factory reset” para limpar todos os dados referentes a ROM original. Depois vá em “install zip from sdcard >> choose zip from sdcard” e instale os arquivos cm-10.0.0-everest.zip e gapps-jb-20121011-signed.zip, nesta ordem. Não é necessário, mas eu gosto de repetir o passo ‘wipe data/factory reset’.

Pronto, Cyanogen instalado. Divirta-se =D.

MacPorts + ccache - Falha na compilação dos pacotes

Published on:

Inventei de ativar o ccache no macports para acelerar a compilação dos pacotes. Segui o tutorial de configuração e fui todo alegre compilar o php54-gd para poder instalar o Elgg e testar o OAuth.

Mas durante a tentativa de instalação ocorreu o seguinte erro:

Erro ao tentar compilar o php54-gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ sudo port -d install php54-gd +t1lib
....
DEBUG: Executing command line:  cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_svn.macports.org_trunk_dports_lang_php/php54-gd/work/php-5.4.11/ext/gd" && ./configure --prefix=/opt/local --with-php-config=/opt/local/bin/php-config54 --with-freetype-dir=/opt/local --with-jpeg-dir=/opt/local --with-png-dir=/opt/local --with-zlib-dir=/opt/local --enable-gd-native-ttf --with-t1lib=/opt/local 
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for a sed that does not truncate output... /opt/local/bin/gsed
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... configure: error: in `/opt/local/var/macports/build/_opt_local_var_macports_sources_svn.macports.org_trunk_dports_lang_php/php54-gd/work/php-5.4.11/ext/gd':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details
Command failed:  cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_svn.macports.org_trunk_dports_lang_php/php54-gd/work/php-5.4.11/ext/gd" && ./configure --prefix=/opt/local --with-php-config=/opt/local/bin/php-config54 --with-freetype-dir=/opt/local --with-jpeg-dir=/opt/local --with-png-dir=/opt/local --with-zlib-dir=/opt/local --enable-gd-native-ttf --with-t1lib=/opt/local 
Exit code: 1
Error: org.macports.configure for port php54-gd returned: configure failure: command execution failed
DEBUG: Error code: NONE
DEBUG: Backtrace: configure failure: command execution failed
    while executing
"$procedure $targetname"
Warning: targets not executed for php54-gd: org.macports.activate org.macports.configure org.macports.build org.macports.destroot org.macports.install
Please see the log file for port php54-gd for details:
    /opt/local/var/macports/logs/_opt_local_var_macports_sources_svn.macports.org_trunk_dports_lang_php/php54-gd/main.log
To report a bug, follow the instructions in the guide:
    http://guide.macports.org/#project.tickets
Error: Processing of port php54-gd failed

Depois de várias tentativas de compilar o pacote, fui consultar o pai dos burros e curiosos o que significava o erro error: cannot compute suffix of object files: cannot compile e achei a solução neste ticket. A solução é simples, só é necessário mudar o dono da pasta onde fica o cache de compilação e depois limpar a pasta do build do pacote que você está tentando instalar, no meu caso o php54-gd.

Os comandos abaixo só irão funcionar se o prefix do macports for /opt/local/ e o cache na pasta ${prefix}/var/macports/build/.ccache.

Mudando permissão da pasta do ccache usado pelo macportsReferência
1
2
3
sudo chown -R macports /opt/local/var/macports/build/.ccache
sudo port clean php54-gd
sudo port install php54-gd +t1lib

MySQL Partitions

Published on:

O MySQL usa um arquivo para armazenar os dados de cada tabela, ou seja, se seu sistem tem um banco com 5 tabelas, ele terá 5 arquivos – um para cada tabela. Se a quantidade de dados de uma tabela crescer muito, o arquivo ficará muito grande e será mais lento pesquisar os dados nessas tabelas. Com PARTITION é possível dividir a tabela em várias partições, criando um arquivo para cada partição, otimizando as operações de leitura e escrita no banco. Essa recurso é muito útil quando:

  • O tamanho do seu índice é maior do que a sua memória RAM
  • Tabelas com muitos registros
  • Seu sistema faz muita consulta em determinadas colunas

Recomendo assistir esse screencast antes: Code Squad: MySQL Partitions

Limitações

  • Máximo de partições: 1024
  • Chaves estrangeiras não suportadas
  • Não suporta índices FULLTEXT
  • Não pode particionar tabela temporária
  • A chave de particionamento deve ser um inteiro

Leitura obrigatória: Restrictions and Limitations on Partitioning

Como fazer

Abaixo a sintaxe de criação de tabela usando PARTITION. Também é possível fazer um ALTER TABLE.

CREATE TABLE SyntaxReferência
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    (create_definition,...)
    [table_options]
    [PARTITION BY
        { [LINEAR] HASH(expr)
        | [LINEAR] KEY(column_list)
        | RANGE{(expr) | COLUMNS(column_list)}
        | LIST{(expr) | COLUMNS(column_list)} }
    [PARTITIONS num]
    [SUBPARTITION BY
        { [LINEAR] HASH(expr)
        | [LINEAR] KEY(column_list) }
      [SUBPARTITIONS num]
    ]
    [(partition_definition [, partition_definition] ...)]]

Tipos

Existem várias formas de criar as partições e serão listadas abaixo:

RANGE

Permite criar ranges para cada partição. No exemplo abaixo são criados 5 partições: p0, p1, p2, p3 e p4. A partição p0 terá todos os registros onde store_id é menor ou igual a 6, na p1 terá os registros maiores que 7 e menores ou igual a 11 e assim por diante. O MAXVALUE é o maior valor possível, ou seja, na partição p4 terá todos os registros maiores que 21.

RANGE PartitioningReferência
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN (21),
    PARTITION p4 VALUES LESS THAN MAXVALUE

);

No MySQL 5.5 foi implementado uma forma de criar partição baseada em intervalos de tempo. Por exemplo:

Usando DATE ou DATETIMEReferência
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE members (
    firstname VARCHAR(25) NOT NULL,
    lastname VARCHAR(25) NOT NULL,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
    PARTITION p0 VALUES LESS THAN (1960),
    PARTITION p1 VALUES LESS THAN (1970),
    PARTITION p2 VALUES LESS THAN (1980),
    PARTITION p3 VALUES LESS THAN (1990),
    PARTITION p4 VALUES LESS THAN MAXVALUE
);

Também é possível criar partições utilizando várias colunas.

RANGE COLUMNS PartitioningReferência
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE rc4 (
    a INT,
    b INT,
    c INT
)
PARTITION BY RANGE COLUMNS(a,b,c) (
    PARTITION p0 VALUES LESS THAN (0,25,50),
    PARTITION p1 VALUES LESS THAN (10,20,100),
    PARTITION p2 VALUES LESS THAN (10,30,50)
    PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
 );

LIST

Com LIST é possível especificar quais são os valores do campo store_id que faz parte da partição. Muito útil quando o conjunto de valores é limitado.

LIST PartitioningReferência
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

COLUMNS

É possível criar partições do tipo RANGE e do tipo LIST usando colunas que não são do tipo inteiros. E no caso do RANGE, é possível criar partições utilizando várias colunas.

Ela permite usar os seguintes tipos de dados ao criar partições: TINYINT, SMALLINT, MEDIUMINT, INT (INTEGER), BIGINT, DATE, DATETIME, CHAR, VARCHAR, BINARY e VARBINARY.

HASH

Como o nome já diz, o particionamento é feito com base O administrador pode escolher uma função hash para aplicada em alguma coluna e especificar a quantidade de partições. Com base nisso, ele descobre a partição usando um simples MOD no resultado do hash usando a quantidade de partições, como no exemplo abaixo:

HASH PartitioningReferência
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;
Descobrindo a partiçãoReferência
1
2
3
MOD(YEAR('2005-09-01'),4)
=  MOD(2005,4)
=  1 -- Está na partição 1

Também é possível utilizar o Linear hashing simplesmente adicionando termo LINEAR ao criar uma partição. Por exemplo:

LINEAR HASH PartitioningReferência
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 4;

Para descobrir como o MySQL encontra a partição no caso do Linear hashing, leia no link

KEY

O KEY é muito semelhante ao HASH. A diferença é que nele não é necessário especificar a função HASH, o próprio MySQL se encarrega de escolhê-lo. Exemplo:

KEY PartitioningReferência
1
2
3
4
5
CREATE TABLE tm1 (
    s1 CHAR(32) PRIMARY KEY
)
PARTITION BY KEY(s1)
PARTITIONS 10;

Ele também aceita o Linear hashing:

LINEAR KEY PartitioningReferência
1
2
3
4
5
6
7
CREATE TABLE tk (
    col1 INT NOT NULL,
    col2 CHAR(5),
    col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;

Referências

Fortemente influenciado pelo Code Squad

MySQL Partitioning

TODO/Leia :)

Subpartitioning

How MySQL Partitioning Handles

Exim4: Configurando o Gmail como Relay

Published on:

Por um tempo eu precisei escrever scripts para mandar as notas pro e-mail pessoal dos meus alunos. Eu configurava o script para usar o SMTP da Google e funcionava muito bem. Mas quando os outros professores me pediam o script eu sempre tinha que lembrar de remover o meu login e minha senha. O mesmo problema ocorre quando publico código/dotfile no github. Então eu decidi configurar um servidor SMTP usando o Gmail como Smarthost que só aceite conexão do localhost.

É importante salientar que essa configuração não é a ideal para quem precisar de um servidor de e-mail robusto, mas para quem está com preguiça de configurar o SMTP de 347 programas diferentes.

Nas configurações abaixo, as palavras HOSTNAME, MEULOGIN, MINHASENHA deverão ser substituídas. O HOSTNAME é o mesmo que está sendo usado no /etc/rc.conf, que por sua vez é o mesmo que está no 127.0.0.1 do /etc/hosts. MEULOGIN e MINHASENHA é o login e senha do Gmail.

Para configurar o Exim4 no ArchLinux usando o servidor SMTP do Gmail é só seguir os passos abaixo usando o usuário root.

Instale o servidor de e-mail Exim

1
# pacman -S exim #Archlinux

Abra o arquivo /etc/mail/exim.conf.

Abaixo de begin routers coloque:

1
2
3
4
gmail_route:
    driver = manualroute
    transport = gmail_relay
    route_list = * smtp.gmail.com

Abaixo de begin transports:

1
2
3
4
5
gmail_relay:
    driver = smtp
    port = 587
    hosts_require_auth = $host_address
    hosts_require_tls = $host_address

Abaixo de begin rewrite:

1
2
3
*@localhost.localdomain MEULOGIN@gmail.com
*@localhost MEULOGIN@gmail.com
*@HOSTNAME MEULOGIN@gmail.com

Abaixo de begin authenticators:

1
2
3
4
gmail_login:
    driver = plaintext
    public_name = LOGIN
    hide client_send = : MEULOGIN@gmail.com : MINHASENHA

Agora salve e saia do arquivo. Para que os usuários não consigam ver teu login e senha mude as permissões com o comando abaixo.

1
# chmod 600 /etc/mail/exim.conf

Edite o arquivo /etc/hosts.allow e coloque exim: localhost para somente aceitar conexões vinda da própria (localhost) máquina.

Agora é colocar no /etc/rc.conf o exim no DAEMONS e pronto!

Servidor de e-mail configurado! =D

PS.: Quando um script tenta descobrir qual é o hostname da máquina, ele pode achar os valores que estão em /etc/hosts. No meu caso eu tenho os seguintes valores pro ip 127.0.0.1: localhost.localdomain, localhost, robinho. Por isso que eu fiz 3 regras. Então qualquer script que queira mandar algum email para qualquer usuário do meu desktop, ele irá mandar um email pro meu gmail, assim eu nunca mais irei esquecer de ver emails que são mandados pro usuário root.

Referências:

Exim with a remote SMTP server

Configuring Exim to use Gmail as a Smarthost

Gmail And Exim4 on Debian