BEGIN
VALUES (CURRENT_USER, CURRENT_TIMESTAMP);
END
Sometimes C++ still surprises me. Consider this code:
namespace ns1
{
class C1
{
};
void f1(const C1&)
{
}
}
int main()
{
ns1::C1 c1;
f1(c1);
return 0;
}
If you think it's wrong and causes a compiler error, you're wrong.
The function "f1" is not in the scope of "main", but its argument has a type of the same namespace, causing the function to be located.
This rule is called Argument-dependent name lookup (or Koenig lookup) and it is also very necessary in relation to operators.
Na parte de expressões SQL, o Firebird 2.5 acrescenta melhorias e novidades. A função agregada LIST (presente desde a versão 2.1) agora aceita qualquer expressão em seu segundo parâmetro, onde o desenvolvedor pode especificar a string de separação dos elementos retornados. Até a versão 2.1.3 era possível apenas o uso de strings constantes nesse parâmetro. Nota: a versão 2.1.4 também deve ser liberada com esta novidade. A listagem 10 mostra a utilidade deste parâmetro, principalmente no desenvolvimento de relatórios, agrupando várias mensagens referentes a um documento em um mesmo registro e mostrando cada mensagem em uma linha.
Listagem 10. Usando a função LIST com expressões no segundo parâmetro.
Operador
|
Descrição
|
X{2}
|
Duas ocorrências de X.
|
X{2,}
|
Duas ou mais ocorrências de X.
|
X{4,6}
|
De quatro a seis ocorrências de X.
|
X?
|
Zero ou uma ocorrência de X.
|
X*
|
Zero ou mais ocorrências de X.
|
X+
|
Uma ou mais ocorrências de X.
|
X|Y
|
X ou Y.
|
_
|
Qualquer caractere - como no LIKE.
|
%
|
Qualquer sequência de caracteres - como no LIKE.
|
(X)
|
Agrupa X para ser tratado pelo operador subsequente.
|
[XYZ]
|
Qualquer caractere igual a X, Y ou Z.
|
[^XYZ]
|
Qualquer caractere diferente de X, Y ou Z.
|
[X-Z]
|
Qualquer caractere entre X e Z.
|
[[:CLASSE:]]
|
Qualquer caractere de uma certa classe, conforme tabela 2.
|
Classe
|
Descrição
|
ALPHA
|
Qualquer caractere entre A e Z.
|
UPPER
|
Qualquer caractere maiúsculo.
|
LOWER
|
Qualquer caractere minúsculo.
|
DIGIT
|
Dígitos de 0 a 9.
|
SPACE
|
Espaço: caractere (ASCII_CHAR) 32.
|
WHITESPACE
|
Todo tipo de espaço: caracteres 9, 10, 11, 12, 13 e 32.
|
Além do comando CREATE COLLATION, mostrado na seção anterior, o Firebird 2.5 acrescenta comandos DDL que aliviam limitações anteriores e outros comandos totalmente novos. Duas limitações existentes nas versões anteriores eram relacionadas à impossibilidade de alteração de colunas COMPUTED BY e views. Era preciso eliminar estes objetos e recriá-los com as alterações. O problema é que o Firebird não permite que um objeto seja eliminado quando este está sendo usado por outro objeto. Algumas ferramentas (como o Flamerobin, por exemplo) geram scripts para eliminar e recriar objetos durante a alteração de um objeto que não era permitida, porém esta não é a solução ideal.
No Firebird, diferentes tabelas ou até mesmo diferentes colunas de uma mesma tabela podem usar diferentes character sets e collates. Isto permite uma grande flexibilidade mas pode causar problemas caso o desenvolvedor ou DBA não se atente às necessidades da aplicação. Por isso, um banco de dados pode ter um character set default, que é automaticamente usado quando não é especificado um character set durante a definição de uma coluna de tipo string. Algo semelhante não existia para collates, sendo que o collate default de cada character set é o modo de comparação binária dos bytes que compõem uma string.
Na nova versão foi introduzido o comando ALTER CHARACTER SET, permitindo a alteração do collate padrão de um character set. Além do comando ALTER CHARACTER SET, agora o collate padrão do character set padrão do banco pode ser definido no momento da criação do banco de dados. A listagem 1 mostra a criação de um banco de dados usando o character set padrão WIN1252 e definindo seu collate padrão para WIN_PTBR. Em seguida o collate padrão do character set UTF8 é alterado para UNICODE_CI_AI.
Listagem 1. Exemplos de alteração de collate padrão.
Desde sua primeira versão, o Firebird foi disponibilizado em dois modos de operação (chamados de arquiteturas) diferentes, a SuperServer e a Classic. Na SuperServer as conexões aos bancos de dados são gerenciadas com múltiplas threads em um único processo do SO, enquanto que na Classic é aberto um processo para cada conexão realizada.
A vantagem da arquitetura SuperServer é que diversas conexões a um mesmo banco de dados são gerenciadas com apenas um cache de dados e metadados. Sua desvantagem é que, internamente, a execução de queries é feita de maneira cooperativa, isto é, em determinados pontos uma query paralisa sua própria execução e passa o controle para que outra query continue executando, não aproveitando adequadamente os recursos de máquinas com mais de um processador ou núcleo. Nota: O time de desenvolvedores do Firebird trabalha para remover completamente esta limitação na versão 3, e a SuperClassic é o primeiro passo em busca desse objetivo. Outra desvantagem da SuperServer é que apenas um processo pode abrir cada banco de dados. Isto causava uma limitação em aplicativos que usavam a biblioteca Embedded, como veremos mais adiante.
Na arquitetura Classic cada processo pode executar queries paralelamente, de forma preemptiva, porém cada um possui seu exclusivo cache. Para manter a integridade, o Firebird precisa realizar comunicação inter-processo através de seu lock manager. Essa comunicação causa uma perda de desempenho em relação à SuperServer. Nesta arquitetura também existia a possibilidade de trabalhar com diversas conexões em apenas um processo, porém com a mesma limitação presente na SuperServer, onde as queries de um mesmo processo rodavam de maneira cooperativa. Além disso, esta possibilidade existia apenas com a versão Embedded para Linux, pois rodando no modo servidor a criação de novos processos era sempre feita automaticamente a cada conexão.
O novo modo SuperClassic é uma mistura das duas arquiteturas preexistentes. Um processo SuperClassic pode gerenciar diversas conexões usando threads, como no SuperServer. Mas, diferentemente do SuperServer, cada conexão possui seu cache exclusivo, como no Classic. Como o cache não é compartilhado, as queries podem rodar de maneira preemptiva, melhorando o desempenho em máquinas multiprocessadas.
A arquitetura SuperServer também teve uma melhoria. Até a versão 2.1 as queries eram sincronizadas por servidor, e na versão 2.5 são sincronizadas por banco de dados. Isto significa que um servidor 2.5 gerenciando conexões a vários bancos de dados aproveitará os recursos de hardware de forma mais satisfatória.
Além de SuperServer e Classic, o Firebird também é disponibilizado como uma biblioteca: a versão Embedded. Até a versão 2.1 a biblioteca Embedded trabalhava no modo SuperServer no ambiente Windows e no modo Classic em outros SOs. Na versão 2.5 a biblioteca Embedded usa o modo SuperClassic em todos os SOs. Como o SuperClassic é o Classic melhorado, tornou-se possível o acesso simultâneo a um banco de dados por diversos aplicativos usando a biblioteca Embedded, removendo esta limitação que existia em ambientes Windows. Nota: o compartilhamento de um banco de dados em vários processos Classic (ou Embedded) é permitido apenas quando todos os processos sejam da mesma arquitetura, 32 ou 64 bits. Com a mudança de arquitetura da versão Embedded, o desenvolvedor precisa verificar se o desempenho de seu aplicativo foi influenciado negativamente, pois a configuração padrão de buffers dos bancos de dados são diferentes nas duas arquiteturas. Esta configuração pode ser ajustada alterando-se o valor do parâmetro DefaultDbCachePages no arquivo firebird.conf ou com o comando gfix -buffers em cada banco de dados.