6 maneiras de fazer a mesma coisa, o que é considerado boas práticas?

As vezes tem tantas maneiras diferentes de fazer o mesmo código que nós ficamos na dúvida quanto a qual maneira usar. O que seria considerado "boa prática" pela comunidade e o que sua equipe entenderia melhor. Suponhamos que você esteja trabalhando dentro de um método de um Domain Service chamado UmDomainServiceChique(objetoDoDominio) que será chamado por uma API. Você tem uma regra de negócio chique para ser verificada que por enquanto chamarei de VerificaMinhaRegraChiqueComplexa(). Você chama UmDomainServiceChique(objetoDoDominio) e caso VerificaMinhaRegraChiqueComplexa() retorne true você vai querer que UmDomainServiceChique faça o que tem que fazer e a api retornar Ok 200, caso contrário você quer que a API responda um erro qualquer, tipo BadRequest, e retornar uma mensagem dizendo que VerificaMinhaRegraChiqueComplexa deu ruim. Eu vejo 6 maneiras de fazer isso, gostaria de saber a opinião de outrs devs sobre qual seria a maneira menos gambiarr

Criando um arquivo unicode com BOM a partir do Delphi 7

Hoje um colega que leu meu post sobre quebra de linhas no Delphi 7 e no Delphi novo teve uma dúvida: Ele não estava conseguindo criar um arquivo de conexão UDL válido. Todos eles davam erro ao abrir.

Ele me disse que usar widestring não resolveu.

Fiquei surpreso do porque ele precisaria gerar o udl pelo Delphi, já que é possível apenas criar um arquivo de texto vazio, renomear ara .udl, e o arquivo será criado normalmente. Mas, ele tinha essa necessidade.

Uma das coisas que descobri hoje é que este arquivo, além de começar com [oledb], deve obrigatoriamente ter o "comentário" abaixo. Ou seja, não é apenas um comentario.

[oledb]
; Everything after this line is an OLE DB initstring

O conteúdo deve ser idêntico a esse. Mas não é apenas o conteúdo. Mesmo que se grave os cabeçalhos corretamente e as strings de conexão, e mesmo que as strings sejam widestrings de dois bytes (unicode) o arquivo em si ainda precisa de alguma coisa.

Essa alguma coisa é o BOM: Abrindo um arquivo que funcione em um editor hexadecimal verá que o arquivo começa com os bytes FF e FE.

Esse FF FE se chama BOM, Byte order mark, (http://en.wikipedia.org/wiki/Byte_order_mark) e diz para o programa que estiver lendo o arquivo qual é o formato (unicode ou não) e qual a orientação (big endian ou litle endian).

O BOM em si é um único char, um widechar de 2 bytes. Como você sabe o tamanho do BOM de cara fica fácil escrever ele no stream: o tamanho será 2, ou 1 * sizeof(widechar). Não concatene o BOM, nem "tipe" ele, pois ele será deformado. Grave-o como um puro array de 2 bytes.

Há alguns programas que não precisam do BOM, pois tentam inferir o tipo de arquivo pelo conteudo. Mas outros, como o programinha do windows que le/edita os udl ou o proprio notepad++ salvam o arquivo já com o BOM, e precisam dele para ler.

Faça o seguinte: crie uma const chamada BOM e grave essa constante no arquivo antes de gravar o restante do conteudo. Repare que o problema não é a quebra de linha, mas sim o BOM.


Mas atenção: não é apenas só por causa do BOM.

Como ja dissemos antes o arquivo deve ter inicialmente 3 linhas onde a primeira é [oledb] e a segunda deve ter exatamente 52 caracteres e deve ser exatamente: "; Everything after this line is an OLE DB initstring"

Exemplo de arquivo udl que se conecta em bases dbase.
[oledb]
; Everything after this line is an OLE DB initstring
Provider=MSDASQL.1;Persist Security Info=False;Data Source=dBASE Files

Exemplo de código usando const ou array de bytes. Perceba que um char pode ser representado pelo seu valor hexadecimal contanto que seja precedido de #$. O BOM é #$FF#$FE.
procedure TForm1.Button1Click(Sender: TObject);
var
  teste: WideString;
const
//  BOM = #$FF#$FE;
    BOM: array[1..2] of Byte = ($ff, $fe); 
begin

  with TFileStream.Create(ExtractFilePath(Application.ExeName)+'\teste.udl', fmCreate) do
  try
    teste :=
      '[oledb]'+#13#10+
      '; Everything after this line is an OLE DB initstring'+#13#10+
      'Provider=MSDASQL.1;Persist Security Info=False;Data Source=dBASE Files';
    //você sabe que o BOM tem um tamanho fixo, que é 2 bytes. O bom é um único widechar de 2 bytes
    Write(BOM, 1 * sizeof(widechar)); //2
    Write(Pointer(teste)^, Length(teste)*SizeOf(WideChar));
  finally
    Free;
  end;

end;


faça o download do exemplo.

Have fun ;)

Comentários

  1. Cara.... Muito obrigado pela dica. Estava precisando somente disso para finalizar meu SETUP para SQL SERVER. Muito bom mesmo! Fico te devendo essa.

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Uso de memória no SQL Server

Busca de CEP com o Lazarus - Parte 1 - UrlEncode

Botão Add This para adicionar seu post em qualquer rede