Salvando objetos com ID definido no Data Mapper (CI)

Desde que comecei a estudar e utilizar o Code Igniter eu recomendo o uso do ORM Data Mapper, que facilita a vida nas consultas ao banco de dados (leia: tutorial do Data Mapper no Code Igniter), esta semana ele mais uma vez se mostrou muito útil enquanto eu fazia a migração do banco antigo do And After para o novo.

Depois de dominar (yeaaaah) relacionamento de tabelas com o Code Igniter (usando o Data Mapper) e finalizar o sistema do And After neste framework estou fazendo a migração de todo o conteúdo para a nova plataforma: textos, comentários, cadastro de usuários, logs, tags, blogs…

Achei que seria extremamente trabalhoso, pois toda a estrutura de banco foi alterada – recomecei o sistema do zero sem pensar na migração, fiz isso para evitar "puxadinhos" e gambiarras (que com o crescimento de sistema, estava cheio) e desenvolver tudo direito, do zero, um sistema novo.

No ônibus voltando para São Paulo fiz em alguns minutos a migração dos usuários e iniciei a dos textos (que será um pouco mais complicada devido aos relacionamentos), mas tive um problema com o Data Mapper: não perder os ID"s dos objetos que estão sendo migrados.

Como salvar um objeto com um ID existente?

O Data Mapper usa o atributo ID do objeto para verificar se ele deve fazer um insert ou um update, se o objeto ID existe ele fará um UPDATE, portanto você não consegue setar o ID de um objeto e usar o $object->save();, pois ele fará um update mesmo que o objeto não exista (e não vai acontecer nada no seu banco).

Para isso o Data Mapper tem a função save_as_new, segue um exemplo abaixo:

$user = new User();
$user->id = 1;
$user->login = "Admin";
$user->password = "password";
$success = $user->save_as_new();

Se não deu nenhum problema no seu banco (neste caso ele deveria estar limpo) você acabou de criar um usuário "Admin" com o id 1na sua tabela.

Problemas comuns

Após fazer a migração pode acontecer problemas ao tentar salvar novos objetos na tabela, isso pode acontecer porque o auto_increment (do ID) não foi atualizado – e está tentando inserir um novo objeto na tabela com um ID que já foi registrado "na mão".

Para facilitar o entendimento vamos a ao exemplo do caso da migração do And After. Existem aproximadamente 1.500 usuários cadastrados no site, após a migração o último ID utilizado na tabela de usuários foi o 1600 (devido a usuários excluídos, testes no banco, etc).

Preciso avisar a minha tabela que o próximo auto_increment (ID) é 1601, e não 1 (que seria o primeiro inserido de forma "natural", sem ID setado). O código abaixo executa esta atualização no banco:

// Update MySQL AUTO_INCREMENT:
$user->db->query("ALTER TABLE `users` AUTO_INCREMENT = 1601;");

Agora a migração da tabela users está completa e é possível utilizar ela normalmente.

Para mais dúvidas sobre o save leia a documentação do data mapper (EN).

Expressão regular com javascript

Expressão regular é um conjunto de padrões que facilita muito o desenvolvimento de determinados sistemas. É um recurso que pouquíssimo explorado pelo que percebo, que muitas pessoas "tem medo" de estudar pela impressão de complexidade que uma expressão regular parece ter, por ser um "conjunto de caracteres sem sentido", como já vi definirem.

Para quem nunca viu, pode até parecer isso mesmo, por exemplo  (w[w|-]*)(.) ou ([a-Z]).

Escrevo para tentar acabar com esse preconceito sobre a complexibilidade das expressões regulares, neste caso especificamente do seu uso no Javascript.

Você não vai ver muito código neste post. Quando me interessei pelo assunto ganhei da Bia o livro Expressões Regulares – uma abordagem divertida e comecei a aplicar ER quando era necessário. Recomendo o livro pois ele é bastante útil como consulta (e ER realmente precisa de consultas recorrentes).

Para que serve uma Expressão Regular

Expressão Regular ou Regular Expression serve para identificar um determinado padrão de caracteres em um texto.

Exemplo de uso: você tem um documento de 500 páginas e quer encontrar preços em reais neste documento. Você cria uma expressão regular que vai encontar o seguinte: "R$ Y,XX"  onde Y pode ser qualquer número (positivo, negativo, com 1 ou infinitas dezenas) e X é uma número de 0 a 9. Simples assim, ao final deste post espero que você esteja apto a "pensar" expressões regulares!

 

Expressões Regulares no javascript

Bem, agora você sabe para que serve, agora vou apresentar as "regras" e significados de cada caracter dentro de uma expressão regular. Você não vai decorar ou aprender tudo, mas sabendo o que é possível e consultando as tabelas abaixo você poderá desenvolver muita coisa e economizar muitas linhas de código.

 

As tabelas abaixo foram traduzidas por Thiago Prado para o iMaster, e ajudam a entender um pouco melhor o significado de cada caracter em uma Expressão Regular.

 

Busca posicionada

Símbolo

Descrição

Exemplo

^

Busca somente no início da string

/^The/ encontra "The" em "The night" mas não em "In The Night"

$

Busca somente no fim da string

/and$/ encontra "and" em "Land" mas não em "landing"



Encontra em qualquer parte da string

/ly/ encontra "ly" em "This is really cool."

B

Encontra qualquer parte que não esteja limitada

/Bor/ encontra “or” em "normal" mas não em "origami."

Literais

Símbolo

Descrição

Alfanumerica

Todos os caracteres alfabéticos e numerais se encontram literalmente. Então /2 dias/ encontrarão "2 days" dentro da string

 

Encontra o caractere de nova linha

f

Encontra o caractere de nova página

 

Encontra o caractere de retorno de carro

 

Encontra o caractere de tabulação horizontal

v

Encontra o caractere de tabulação vertical

xxx

Encontra o caractere ASCII expresso por um número octal xxx.
"50" encontra o caractere parênteses esquerdo "("

xdd

Encontra o caractere ASCII expresso por um número hexadecimal dd.
"x28" encontra o caractere parênteses esquerdo "("

uxxxx

Encontra o caractere ASCII expresso por UNICODE xxxx.
"u00A3" encontra "£".

 

 

Classes de Caracteres

Símbolo

Descrição

Exemplo

[xyz]

Encontra qualquer caractere que estiver dentro do grupo. Você pode usar hífen para denotar escala. Por Exemplo. /[a-z]/ encontra qualquer letra do alfabeto alphabet, /[0-9]/ encontra qualquer dígito

/[AN]BC/ encontra "ABC" e "NBC" mas nao “BBC" desde que a letra “B” nao estao nogrupo.

[^xyz]

Encontra qualquer caractere que não estiver dentro do grupo. O circunflexo indica que nenhuma caractere deve estar na string.
NOTA: O circunflexo usado dentro da classe de caractere é diferente do que denota o início da string, não se confundam. A negação aqui só é permitida dentro dos sinais

/[^AN]BC/ encontra "BBC" mas nao "ABC" ou "NBC".

.

(Ponto). Encontra qualquer caractere exceto o caractere de nova linha ou terminador de linha Unicode

/b.t/ encontra "bat", "bit", "bet" e assim por diante

w

Enconta qualquer caractere alfanumérico incluindo underscore. Equivalente a [a-zA-Z0-9_]

/w/ encontra "200" em "200%"

W

Encontra qualquer caractere que não se encontra na classe dos alfanuméricos. Equivalente a [^a-zA-Z0-9_]

/W/ encontra "%" em "200%"

d

Encontra qualquer dígito. Equivalente a [0-9]

 

D

Encontra qualquer caractere que não seja um digito. Equivalente a [^0-9]

/D/ matches "No" in "No 342222"

s

Encontra qualquer caractere que equivale a um espaço. Equivalente a [ vf]

 

S

Encontra qualquer caractere que não equivale a um espaço. Equivalent to [^ vf]

 

Repetição

Símbolo

Descrição

Exemplo

{x}

Encontra exatamente x ocorrências na regular expression

/d{5}/ encontra 5 digitos

{x,}

Encontra x ou mais ocorrências na regular expression

/s{2,}/ encontra no minimo 2 caracteres de espaço em branco

{x,y}

Encontra x para y numero de ocorrências na regular expression

/d{2,4}/ encontra no minimo 2 mas nao mais que 4 digitos

?

Encontra zero ou nenhuma ocorrência. Equivalente a {0,1}

/as?b/ encontra "ab" ou "a b".

*

Encontra zero ou mais ocorrências. Equivalente a {0,}

/we*/ encontra "w" em "why" e "wee" em "between", mas nao em "bad"

+

Encontra uma ou mais ocorrências. Equivalente a {1,}

/fe+d/ encontra tanto em "fed" quanto em "feed"

Alternação & Agrupamento

Símbolo

Descrição

Exemplo

( )

Agrupamento de caracteres para criar uma cláusula de condição. Pode estar aninhado

/(abc)+(def)/ encontra um ou mais ocorrencias de "abc" seguido por uma ocorrencia de "def"

|

Combina cláusulas de condições dentro de uma regular expression e então encontra qualquer uma das cláusulas. Similar à expressão "OR"

/(ab)|(cd)|(ef)/ encontra "ab" ou "cd" ou "ef".

Backreferences

Símbolo

Descrição

Exemplo

( )

Encontra uma cláusula entre parênteses. n é o número de cláusulas para a esquerda da backreference

(w+)s+1 encontra quaisquer palavras que ocorra duas vezes na mesma linha, como "hubba hubba." O 1 denota que a primeria palavra depois do espaço deve encontrar a porção da string que foi encontrada no último commando dentro de parênteses. Se existisse mais de um comando dentro de parênteses, você deve usar 2 ou 3 para encontrar o apropriado agrupamento da esquerda da backreference. Até 9 backreferences podem ser usadas no padrão da string

 

Modificadores de padrão

 

Propriedade

Descrição

Exemplo

i

Ignora se é minúscula ou maiúscula

/The/i encontra "the" e "The" e "tHe"

g

Pesquisa Global para todas as ocorrências do padrão

/ain/g encontra os dois "ain" em "No pain no gain", ao inves de apenas o primeiro

gi

Pesquisa Global, e ignorar caso

/it/gi encontra todos "it" em "It is our IT department"
lastIndex

lastIndex

Armazena a posição da última pesquisa bem sucessida realizada na string. Se nada for encontrado, a propriedade lastIndex será colocada como –1

 

$n

n representa o numero de 1 a 9
Armazena os nove mais recentes pesquisa dentro de parênteses encontradas. Por exemplo, se o padrão usado por uma regular expression para a última pesquisa foi /(Hello)(s+)(world)/ e a string pesquisada foi “Hello world” o conteúdo de RegExp.$2 poderia ser qualquer caractere entro “Hello” e “world”

 

source

Armazena a copia do padrão da regular expression

 

Entendendo os métodos usados pelas expressões regulares

Método

Descrição

exec

Um método RegExp que executa pesquisas em uma string. O mesmo retorna um array das informações obtidas

test

Um método RegExp que testa uma pesquisa em uma string. O mesmo retorna true ou false

match

Um método de String que executa uma pesquisa em uma string. O mesmo retorna um array das informações obtidas ou nulo se nada for encontrado

search

Um método de String que testa uma pesquisa em uma string. O mesmo retorna o índice do resultado, ou -1 se a pesquisa falir

replace

Um método de String que executa uma pesquisa em uma string, e substitui o resultado encontrado por uma substring

split

Um método de String que usa uma regular expression ou uma string para quebrar uma string em uma array de substrings

 

 As tabelas são do iMaster (Thiado Prado) e são ótimas para referências – você não vai decorar tudo de uma vez, consultas são importantes. 🙂

 

.exec() – Testando se uma string casa com a ER

No javascript o comando .exec() testa uma string para verificar se ela casa com a sua expressão regular. Se casar, o retorno é a consulta, senão o retorno é  null.

Exemplo (da W3C):

<script type="text/javascript">

var str="Hello world!";
//look for "Hello"
var patt=/Hello/g;
var result=patt.exec(str);
document.write("Returned value: " + result);

//look for "W3Schools"
patt=/W3Schools/g;
result=patt.exec(str);
document.write("<br />Returned value: " + result);

</script>

 

Na primeira consulta teremos o retorno "Hello" printado na tela, na segunda teremos "null".

 

Finalizando, expressão regular pode parecer muito complicado quando você não sabe o que nada significa e tenta decifrar (adivinhar, né?) o significado de algo como:

(w[w|-]*)(.)*]/)

 

Gostaria de ter o costume de utilizar mais ER´s, a criação deste post foi uma forma de tentar me estimular ao uso, pois é um método bastante performático, com menos código e mais legível (depois que você compreende o funcionamento) de executar algumas funções avançadas que exigiriam infinitos alguns "loops e ifs" – a arte da gambiarra.

Em alguns posts mais pra frente vou postar alguns estudos que fiz e exemplos práticos do uso das ER´s.

Fica novamente a recomendação de um livro muito útil para consultar – Expressões Regulares, uma abordagem divertida.

Variáveis multiline no javascript

É cada vez mais comum manipular uma quantidade enorme de html através do Javascript, seja usando Ajax ou apenas alterando elementos estáticos do html.

Alguns códigos que eu vejo tem "tripas" gigantescas de código html tudo na mesma linha, para se manter dentro de uma variável. Identação zero, não precisa dizer que o código é praticamente ilegível, né?

//Exemplo de código ilegível
var structureTable = "<table><tbody><tr><td>Name</td><td>ID</td><td>Value</td><td>Tax</td><td>Quantity</td></tr><tr><td>Name</td><td>ID</td><td>Value</td><td>Tax</td><td>Quantity</td></tr></tbody></table><hr /><h2>Tabela 2</h2><table><tbody><tr><td>Name</td><td>ID</td><td>Value</td><td>Tax</td><td>Quantity</td></tr><tr><td>Name</td><td>ID</td><td>Value</td><td>Tax</td><td>Quantity</td></tr></tbody></table>";

Neste caso a estrutura nem é tão complicada, duas tabelas apenas. Mas as vezes a coisa fica FEIA quando existem blocos muito grande de HTML que devem ser manipulados pelo javascript.

Uma solução para lidar com este problema é usar Ajax e carregar o bloco de javascript de um arquivo HTML separado e inserir ele no seu DOM, mas vejo isso como uma requisição desnecessária ao servidor – você fará uma requisição para um conteúdo que não é dinâmico.

A solução que proponho para lidar com strings que são códigos de HTML são variáveis com mais de uma linha no javascript.

Variáveis multiline no javascript

A mesma "structureTable" que defini no exemplo acima vou definir agora, usando quebra de linha para variáveis do JS. Para sinalizar a quebra de linha no Javascript você só precisa usar uma barra invertida e continuar a variável na próxima linha.

//Exemplo de código legível
var structureTable = "<table>\
<tbody>\
   <tr>\
     <td>Name</td>\
     <td>ID</td>\
     <td>Value</td>\
     <td>Tax</td>\
     <td>Quantity</td>\
   </tr>\
</tbody>";

 

E pronto, você tem sua variável legível e muito mais fácil de dar manutenção depois.

Mercado de trabalho – A vaga de PHP é sua…

As vezes vejo no Twitter algumas oportunidades de emprego para desenvolvedores, repasso algumas no twitter do O Desenvolvedor (follow us!) e tem algumas que são muito engraçadas tristes.

Exemplo de uma que li recentemente, de uma agência de SP e RJ:

Para uma vaga de web-developer Júnior:

Pré-requisitos:

  • Sólidos conhecimentos de HTML/CSS (W3C), JavaScript (Ajax), PHP e MySQL;

  • Experiência com administração remota de plataformas UN*X;

  • Entendimento de linguagens de programação de uso genérico (C/C++/Java/Perl/Python/etc);

  • Capacidade de elaborar soluções próprias em programação;

  • Possuir um portfólio online.

Desejável conhecimento de:

  • ActionScript 3;

  • Frameworks de JavaScript (jQuery/YUI/etc);

  • Shell scripting;

  • Especificações do protocolo HTTP/1.1;

  • Uso das APIs dos webservices (Flickr/Google/Twitter/YouTube/etc);

  • WordPress (elaboração de temas e/ou plugins).

 

Destaque para "linguagens de programação de uso genérico (C/C++/Java/Perl/Python)", especificações do protocolo HTTP/1.1 e shell scripting.

Oportunidade de trabalho…

A oportunidade existe desde que você seja um back-front-end developer com conhecimentos em gerenciamento e protocolo de redes, domine frameworks e algumas linguagenzinhas genéricas que vão do ASP, PHP, Python até o Cobol.

Profissional transformer
(ou o famoso tapa-buraco)

 

Mas nem tudo é tristeza, ainda existem algumas empresas que conseguem dividir e focar em pessoas com conhecimentos específicos. Mas só algumas, enquanto isso o Roberto Justus tem uma mensagem a você, que está procurando uma vaga de programador PHP:

 

E você, quer compartilhar sua opinião sobre o mercado de trabalho para programadores? Comenta aí!