Trabalhar com anexos de arquivo no LCLSX

Este artigo descreve como você pode trabalhar com anexos de arquivo no Lotus Connectors LotusScript Extension (LCLSX). Mostramos como o LCLSX lida com anexos de arquivo e apresentamos um aplicativo de amostra para demonstrar o processo de anexação de arquivo.

Andre Guirard, EI Product Developer, IBM

Andre Guirard é membro da equipe de desenvolvimento do Notes Client e Domino Designer. Desenvolvedor do Notes há muito tempo, Andre agora se concentra na ativação de desenvolvedores. Ele frequentemente ministra palestras na Lotusphere e outras conferências IBM, e seus artigos já apareceram no developerWorks: Lotus (LDD), na revista The View e em outros lugares. Em seu tempo livre, ele ajuda sua esposa nos projetos de jardinagem.



01/Out/2012

O Lotus Connectors LotusScript Extension (LCLSX) permite facilmente a sincronização de campos simples entre bancos de dados Notes e bancos de dados relacionais -- campos de texto, data e números não representam problemas. É possível até mesmo armazenar campos de rich text como texto simples ou armazená-los em um campo BLOB relacional (embora a codificação binária de um campo de rich text não seja utilizável, exceto pelo Lotus Notes/Domino).

Entretanto, anexos de arquivo são um pouco mais complicados. Nem as classes nativas do Notes nem o LCLSX têm suporte para acesso direto aos dados em um anexo de arquivo. A única maneira de extrair um anexo de arquivo do Lotus Notes é desanexá-lo para o disco, e a única maneira de criar um anexo de arquivo é de um arquivo de disco. Mas o LCLSX pode facilitar as coisas realizando a desanexação e anexação automaticamente enquanto você trabalha nos dados do Notes.

Este artigo apresenta uma explicação passo a passo de um aplicativo de amostra para copiar anexos de arquivo do Notes e para um banco de dados relacional. Presumimos que você já tenha alguma experiência com o uso e a terminologia do LCLSX. Caso não tenha, consulte o IBM Redbook, Implementing IBM Lotus Enterprise Integrator 6. Esse livro inclui um capítulo no LCLSX que oferece uma boa base dessa tecnologia com muitos exemplos.

A teoria geral dos anexos de arquivo no LCLSX

O conector do Notes do LCLSX contém as seguintes propriedades que são usadas para tratar anexos de arquivo:

  • O LoadFile é uma propriedade booleana que, quando definida para True, adiciona um campo especial chamado FILE ao conjunto de resultados retornado pelo método Select. Além disso, sempre que você realiza uma Busca em um documento do Notes, quaisquer anexos de arquivo no documento são copiados para um diretório de arquivo local, e o campo FILE contém os nomes de arquivo (como uma lista de diversos valores). Ao atualizar ou inserir um documento do Notes, quaisquer arquivos listados no campo FILE são anexados ao documento do Notes.
  • O FilePath é um valor de cadeia de caracteres que define o caminho do arquivo do diretório em que anexos são desanexados quando um documento do Notes é buscado, se LoadFile for True. Se deixado em branco, o diretório atual é usado. Não deixe em branco! O diretório atual normalmente está no diretório do programa Notes, que contém muitos dos arquivos que você não deseja acidentalmente substituir desanexando um arquivo que tenha o mesmo nome.
  • CopyFile é uma propriedade booleana que, quando definida para True, adiciona um campo especial chamado LCXFILE à lista de campo do conjunto de resultados retornado pelo método Select. Se você inserir ou atualizar outro documento do Notes usando essa lista de campo, ele copia todos os anexos para o novo documento.

As duas primeiras propriedades são aquelas que usamos neste artigo. CopyFile é útil apenas para transferir anexos entre dois bancos de dados do Notes, não entre o Lotus Notes e bancos de dados relacionais.

Assim, temos uma maneira de colocar os dados de anexo do Notes em um arquivo. A próxima etapa é armazenar os conteúdos do arquivo em um campo binário no banco de dados relacional. Para fazer isso, é preciso colocar os dados do arquivo binário em um objeto LCField. A ferramenta que nos permite fazer isso é o conector File. O conector File acessa dados de um sistema de arquivos de uma maneira que faz com que se pareçam uma tabela relacional. Cada arquivo é representado por uma linha no conjunto de resultados, e todas as tabelas de diretório, não importa o sistema operacional que você usa, contêm as mesmas quatro colunas:

  • Filename é o nome do arquivo sem o caminho de arquivo completo.
  • Contents são os dados no arquivo na forma binária ou de texto, dependendo da configuração da propriedade binária do conector. Para nossos objetivos, desejamos usar o formato binário de modo que os conteúdos exatos do anexo sejam preservados.
  • Timestamp identifica quando um arquivo foi modificado pela última vez.
  • Size é o tamanho do arquivo em bytes.

O processo geral para exportar do Lotus Notes é buscar dados de um documento do Notes usando o conector do Notes, que automaticamente desanexa um arquivo para cada anexo. Use o conector File para ler os arquivos na memória e qualquer conector relacional para armazenar os dados de arquivo em uma coluna binária. Para fazer o caminho inverso, é possível inserir registros em um conector File, que cria os arquivos.

Seja importando ou exportando, as instruções para configurar as conexões são basicamente as mesmas. Aqui estão as instruções que a nossa amostra de exportação usa para configurar o conector Notes (que são iguais para leitura e gravação).

	Dim lcconNotes As New LCConnection("notes")
	lcconNotes.server = db.server
	lcconNotes.database = db.filepath
	lcconNotes.metadata = "Villain"
	lcconNotes.FilePath = containing_folder + "\" + foldername
	lcconNotes.LoadFile = True

Isso presume que você está usando o sistema operacional Windows, pois usamos "\" como separador de diretório. A seguir, configure o conector de arquivo desta maneira:

	Dim lcconFiles As New LCConnection("file")
	lcconFiles.Database = containing_folder
	lcconFiles.Metadata = foldername
	lcconFiles.Binary = True

A instrução final especifica que os dados do arquivo são binários -- o conector File não tentará interpretar os bytes como caracteres. No código de amostra, usamos uma classe personalizada para criar um diretório temporário que é automaticamente excluído ao final da execução.


O aplicativo de amostra

É possível fazer download de um banco de dados do Notes de amostra contendo o código discutido. O aplicativo é "Dick Tracy Crime Files." Tracy, um famoso detetive policial, é um antigo fã dos produtos Lotus. Ele criou esse banco de dados para rastrear criminosos conhecidos. As fotografias de identificação policial dos criminosos são armazenadas em anexos de arquivo JPEG. Precisamos integrar esses dados do Notes com um banco de dados relacional em que os JPEGs sejam armazenados em uma coluna binária.

Os documentos Villain do Notes contêm o campo ID, uma chave exclusiva usada para relacionar os registros a outras tabelas relacionais. A tabela que contém os dados que precisamos atualizar possui três colunas:

  • VillainID, em que devemos copiar o campo ID do Lotus Notes. Um criminoso pode ter várias fotos de identificação policial, assim, essa coluna não contém valores exclusivos.
  • Filename, contendo o nome original do arquivo JPEG. Os campos VillainID e Filename considerados em conjunto devem ser exclusivos.
  • Filedata, os conteúdos do arquivo binário.

Nos nossos scripts de amostra, há também sincronização de outros campos do Notes para outras tabelas, mas estamos preocupados apenas com os anexos de arquivo.

Configurando para executar os scripts de amostra

É possível executar os scripts a partir de um Notes client. Eles, é claro, precisarão de um banco de dados relacional seu ao qual exportar e do qual importar. Qualquer banco de dados serve -- o Microsoft Access funcionará. Os scripts de amostra automaticamente criam as tabelas necessárias se elas ainda não existirem, desde que o login do banco de dados relacional usado tenha esse nível de acesso.

Como escritos, os scripts leem as informações de conexão de um banco de dados DECS (ou LEI) Administrator em um servidor Domino (decsadm.nsf). Esse banco de dados pode ser local, se você preferir. Não é preciso executar DECS ou LEI, mas deve ter um banco dados decsadm.nsf. É possível usar o modelo DECS Administrator (decsadm.ntf) para criá-lo. Ou, se preferir, é possível codificar as informações de conexão em uma biblioteca de scripts. Em qualquer caso, você deseja editar essa biblioteca de scripts, que é chamada Customize Connections. Na seção (Options), há várias instruções Const. Ajuste os valores desses parâmetros para dizer ao script onde procurar as informações de conexão:

  • O nome YOUR_CONNECTION_DOC contém o nome do documento Connection que o script procurará no banco de dados DECS Administrator.
  • VILLAINS_MAIN, VILLAINS_CRIMES e VILLAINS_ATTACHMENTS contêm os nomes de três tabelas para as quais os dados são exportados.
  • YOUR_DECS_SERVER é um lugar em que é possível colocar o nome do servidor em que o banco de dados DECS Administrator pode ser encontrado. Para local, deixe em branco.

Se preferir codificar o tipo, o nome, o ID e a senha do banco de dados relacional, visite cada um dos módulos nesse script para obter instruções sobre como customizá-lo.

Depois de customizar essa biblioteca, crie o documento Connection inserido em YOUR_CONNECTION_DOC. Então você deve estar pronto para começar.

Executando os scripts de amostra

Abra o banco de dados no Notes client e acesse Villains \ pela visualização de ID. Ele contém quatro documentos de amostra. O menu Actions lista os agentes numerados que devem ser executados em sequência.

1: Criar/limpar tabelas
Esse agente usa o método Action com o argumento LCACTION_TRUNCATE para remover quaisquer dados que possam estar nas três tabelas relacionais. Se as tabelas não existirem, o script as cria. Você pode estar interessado em consultar o script para ver como criar tabelas com o LCLSX, mas, porque esse não é objetivo deste artigo, não entraremos em detalhes.

2: Exportar Villains para RDB
Esse agente implementa o processo de exportação discutido anteriormente. O desempenho não é uma grande consideração nesse script porque há apenas quatro documentos, mas, para servir como um bom exemplo para os seus aplicativos em que o desempenho possa ser crucial, seguimos as melhores práticas estabelecendo relacionamentos entre os campos a serem copiados primeiro, de modo que a cópia aconteça automaticamente sem que os dados precisem ser movidos de campo para campo dentro do loop do programa principal.

Isso é feito criando fieldlists que contenham referências aos mesmos objetos de campo. O LCField é um objeto separado, então ele pode ser consultado por várias fieldlists, que podem, cada uma, ser conhecidas por um nome diferente. Na Figura 1, um retângulo representa um elemento de fieldlist, e uma forma oval é um objeto LCField. Conectar linhas mostra que elementos fieldlist referem-se a que objetos LCField.

Figura 1. Fieldlists
Fieldlists

Quando se realiza esse tipo de programação, sugerimos sempre criar um diagrama. Ele pode nem sempre ser assim tão organizado, e frequentemente é mais complexo. Configurando as fieldlists dessa maneira, é possível ler um documento do banco de dados do Notes, e os dados que você deseja gravar nas outras duas tabelas já estão nas fieldlists inseridas no banco de dados relacional. Conforme você lê o registro do Notes, os arquivos são criados automaticamente, e podem ser lidos com o conector File -- e os dados já estão na fieldlist inserida na tabela de anexos no banco de dados relacional.

Aqui está o código que cria essas fieldlists vinculadas:

Call lcconNotes.Select(Nothing, 1, flNotes) ' select all docs, init flNotes
Call lcconFiles.Select(Nothing, 1, flFiles) ' init flFiles (no files yet)
Call flDest.MapName(flNotes, "ID,Name,Location,Body", "VillainID,Name,Hideout,Comments")
Set fldID = flDest.Lookup("VillainID")
Call flDestAtt.MapName(flFiles, "Filename,Contents", "Filename,Filedata")
Call flDestAtt.IncludeField(3, fldID, "VillainID")
Call flCrimes.MapName(flNotes, "ID,Crimes", "VillainID,Crime")
Set fldCrimes = flNotes.Lookup("Crimes")

As duas instruções Select criam os objetos de campo para as duas fieldlists de origem. Queremos ler todos os documentos do Notes, assim, a primeira instrução Select tem uma ação dupla. Porém, ainda não há nenhum arquivo no diretório temporário, então a instrução Select no conector File tem como objetivo apenas inicializar a fieldlist.

As instruções que se seguem criam novas referências para os mesmos campos e inserem-nas em outras fieldlists. Depois disso, o loop principal do programa de exportação é bastante simples:

Do While lcconNotes.Fetch(flNotes) > 0
	' The Fetch has also detached all attachments into 
	' the temp directory.
	Call lcconDest.Insert(flDest)   ' create main villain record.
	Call lcconDestCrimes.Insert(flCrimes)   ' insert multiple crimes 
	' rows in one operation.
	Call lcconFiles.Select(Nothing, 1, Nothing) ' see what files are 
	 ' in the temp directory.
	Do While lcconFiles.Fetch(flFiles)
		Call lcconDestAtt.Insert(flDestAtt) ' insert one file in attachment 
		' table.
	Loop
	Call lcconFiles.Action(LCACTION_TRUNCATE) ' get rid of the 
	' attachment files.
Loop

A Busca no fieldlist flNotes também criou arquivos no diretório temporário. O script seleciona no conector File para obter uma lista desses arquivos e também para ler seus conteúdos. Observe que o terceiro argumento para a instrução Select é Nothing. Normalmente, forneceríamos uma fieldlist em branco de modo que os campos do conjunto de resultados pudessem ser preenchidos, mas já temos a fieldlist preenchida de que precisamos para buscar os resultados, então não há sentido em desenvolver outra. Na verdade, a que temos é melhor que uma nova porque ainda não está vinculada às fieldlists de saída.

Alguns pontos dignos de nota sobre este programa:

  • Temos três objetos LCConnection que apontam para o banco de dados de destino, um para cada tabela. Os conectores para as tabelas de anexo e principal são direcionados para o banco de dados, enquanto a conexão para a tabela de crimes passa por um metaconector Collapse/Expand, que converte automaticamente entre um campo de diversos valores do Notes e diversas linhas em uma tabela relacional de um para muitos. Este último está além do escopo deste artigo, mas você pode desejar consultar o código para ver como é feito.
  • A fieldlist do Notes contém um campo FILE, que contém uma lista dos caminhos completos dos arquivos desanexados. Entretanto, não precisamos usar esse campo durante a exportação. Buscamos os nomes de arquivo e os conteúdos diretamente do disco com o conector File, assim, obtemos as mesmas informações dessa maneira. Seria uma história diferente se o diretório contivesse outros arquivos, mas criamos um novo diretório temporário especificamente para que não precisemos nos preocupar com isso.
  • Embora buscar um documento do Notes possa automaticamente copiar os anexos de arquivo para o disco, não há objetivo em remover automaticamente os anexos depois de ter terminado de usá-los. No final do loop, o método Action apaga todos os arquivos do diretório temporário truncando a tabela que contém os conteúdos do diretório.
  • Mapeamos o campo rich texto Body do documento do Notes para um campo BLOB binário em um banco de dados relacional. Isso copia uma imagem binária bruta do campo rich text para o campo BLOB. Esses dados estão em um formato proprietário que não são utilizáveis, exceto importando-os de volta para o Lotus Notes. Embora os ícones para os anexos do arquivo possam aparecer dentro do campo rich text ao editar o formulário, os anexos são armazenados separadamente do rich text -- copiar o rich text não copia os anexos. Entretanto, isso proporciona uma maneira de realizar cópias de backup de imagens integradas e outras parafernálias que aparecem no rich text, que mais tarde podem ser restauradas no Lotus Notes.
  • As buscas do loop interno, porém, encontra muitos anexos no diretório temporário e insere-os na tabela relacional de anexos, usando a combinação de VillainID e nome do arquivo para dar ao registro um identificador exclusivo. Internamente, o Notes impede nomes de anexo duplicados dentro do mesmo documento renomeando qualquer um que não seja exclusivo, assim chaves duplicadas não devem ser um problema.
  • Conforme o loop principal executa, uma função customizada chamada DebugStr é usada para criar as descrições de cadeia de caracteres dos dados sendo gravados em disco. Caixas de mensagens exibem informações sobre cada conjunto de registros como estão escritos. As linhas para a saída de depuração foram omitidas do código precedente para que seja possível ver apenas a funcionalidade para mover os dados.

3. Importar do RDB
O próximo agente realiza o inverso do agente anterior: cria novos documentos do Notes com anexos de arquivo dos dados no banco de dados relacional. Porque não desejamos excluir nossos registros de dados de origem, criamos um segundo formulário do Notes (como o formulário Villain, mas chamado Bad Guy), e esse é o tipo de documento que o script de importação cria.

Devemos criar os arquivos a partir dos dados nos bancos de dados relacionais, então usamos uma chave da tabela relacional Villains para selecionar na tabela relacional de anexos. Usamos esses dados para criar os arquivos no disco inserindo-os no conector File. Então inserimos no conector Notes, e essa operação captura os arquivos do disco e cria automaticamente os anexos do arquivo Notes.

Entretanto, há uma diferença importante entre usar a propriedade LoadFile do conector do Notes para ler e usá-la para gravar. Ao ler, é possível ignorar o campo FILE na fieldlist do Notes e ver quais arquivos foram criados. Mas, ao gravar, precisamos usar o campo FILE para informar ao Lotus Notes o caminho de arquivo completo de cada arquivo que desejamos anexar. Ele pegará simplesmente todos os arquivos em um diretório de destino.

O campo FILE é especial. Além do nome, ele tem códigos de campo virtual especial associados a ele que indicam ao conector do Notes para dar a ele um tratamento especial. Isso indica para você distinguir entre um campo com uma funcionalidade de lista de anexo do arquivo e um campo regular que apenas coincide de ser chamado de FILE. Há vários nomes de campo especial usados pelo conector do Notes, e todos têm o sinalizador virtual.

NOTA: O sinalizador de campo virtual não deve ser confundido com DECs e a atividade de LEI Virtual Fields, que busca informações em tempo real de um banco de dados relacional. Os nomes são similares, mas os conceitos são muito diferentes.

Antes de ir para o loop principal, o script de importação desenvolve um conjunto de fieldlists vinculados, que é muito similar ao mostrado anteriormente, incluindo o campo FILE especial. (Traçar o diagrama desses relacionamentos de campo é deixado como um exercício para o leitor.) Como vimos anteriormente, a maneira fácil de criar uma fieldlist que combine com a sua tabela é usar Select para recuperar uma descrição da tabela. Isso é especialmente verdadeiro quando campos especiais, como campos virtuais e de diversos valores, estão na lista. Porém, por que facilitar quando um exemplo instrutivo pode ser criado fazendo da maneira mais difícil? Aqui está o código para criar seu próprio campo virtual FILE a partir do zero:

Set fldFiles = flNotes.Append("FILE", LCTYPE_BINARY)

O campo é do tipo binário, mas não é um campo BLOB. Campos binários também são usados para armazenar valores de campo especial do Notes, como campos de rich text e de diversos valores.

Call fldFiles.SetFormatStream( , , LCSTREAMFMT_TEXT_LIST)

Atribuímos o tipo de campo binário, um campo de texto do Notes de diversos valores.

Call fldFiles.SetVirtualCode(lcconNotes.GetPropertyInt(LCTOKEN_CONNECTOR_CODE))

A função SetVirtualCode requer um argumento que indique que conector ou conexão deve dar a esse campo tratamento especial. Conectores diferentes podem ter diferentes nomes de campo que considerem especiais, então isso permite-nos designar o campo como especial para o Lotus Notes, mas não para outros conectores. Essa é uma das maneiras pelas quais podemos acessar a funcionalidade exclusiva de diferentes backends. O sinalizador que atribuímos aqui indica ao Lotus Notes para prestar atenção especial ao campo.

A propriedade do código Connector de todas as conexões do Notes retorna o mesmo valor numérico. O código Connection, porém, é exclusivo para um único objeto LCConnection. Configurando o código virtual que pertence à conexão, em vez do conector, é possível carregar uma lista de nomes de um documento do Notes com uma conexão do Notes (que trata FILE como apenas um simples campo de diversos valores), mas vincula esse campo a uma fieldlist associada a uma segunda conexão, que trata o campo FILE como especial e localiza esses arquivos em disco. O campo FILE precisa conter o caminho completo de cada um dos arquivos que você deseja anexar, e não apenas os nomes de arquivo.

O loop principal da função de importação deve desenvolver essa lista de valores para cada registro Villain que lê do banco de dados relacional. Aqui está o código:

Do While lcconVillains.Fetch(flVillains) > 0
	Call lcconCrimes.Select(flVillains, 1, Nothing) ' read thru metaconnector, 
	' so there's always at most one result.
	If lcconCrimes.Fetch(flCrimes) = 0 Then
		fldCrimes.Value = "" ' if they have no crimes, erase value left over
		' from previous iteration.
	End If
		
	strFilenames = ""
	Call lcconAttach.Select(flVillains, 1, Nothing)
	' Loop thru list of attachment relational records associated with 
	' current key, and detach each file to temp dir.
	Do While lcconAttach.Fetch(flAttach)
		Call lcconFiles.Insert(flFiles)   ' copy the file contents into a 
		' disk file. Build a delimited string of the full filepaths of the 
		' files we detach.
		strFilenames = strFilenames & NEWLINE & dirTemp.fullpath & 
		  "\" & fldFilename.Text(0)
	Loop
	' If there are attachments, construct a string that contains a multivalue 
	' where each value is the full path of one file.
	If strFilenames <> "" Then
		lcstrFilenames.Value = Split(Mid$(strFilenames, 2), NEWLINE)
	Else
		Call lcstrFilenames.Clear
	End If
	Call fldFiles.SetStream(1, lcstrFilenames)  ' set FILE multivalue field 
	' to list of files to attach.
	Call lcconNotes.Insert(flNotes)
	Call lcconFiles.Action(LCACTION_TRUNCATE) ' get rid of temp 
	' attachment files.
Loop

A variável lcstrFilenames é um objeto LCStream. LCStreams são os objetos usados para armazenar os dados para todos os textos e objeto LCField binário. Eles não são muito usados, mas são muito práticos quando é necessário trabalhar diretamente com os dados de um campo binário, como um valor múltiplo do Notes. É possível simplesmente atribuir o texto de um campo de diversos valores, e a classe LCStream divide-se em valores diversos para você, mas usa uma vírgula, em vez de um delimitador, então isso funciona apenas quando os valores dos dados não contêm vírgulas.

Observe o seguinte:

  • O campo VillainID na fieldlist flVillains é definido para ser uma chave key (LCFIELDF_KEY). Esse sinalizador é ignorado pela operação Fetch que carrega os dados na fieldlist, mas torna possível usar flVillains como o argumento dos critérios de seleção para um Select obter os crimes relacionados e registros anexos.
  • Quando selecionamos entre as duas tabelas selecionadas, fornecemos Nothing como o terceiro argumento. Não precisamos ter as fieldlists do conjunto de resultados desenvolvidas para nós durante Select porque já as possuímos. E aquelas que possuímos já estão compartilhando campos com outras fieldlists, assim, são melhores do que as novas seriam.
  • A expressão dirTemp.fullpath refere-se a uma propriedade de classe customizada usada para criar diretórios temporários e excluí-los automaticamente quando tiver concluído. Você pode considerar a classe útil em outros scripts. Essa propriedade retorna o caminho completo do diretório temporário.
  • Mais uma vez, usamos "\" como o delimitador do diretório, que funciona apenas com sistemas operacionais Windows.
  • Não é preciso usar o caminho de arquivo completo ao atribuir o campo FILE. Em vez disso, é possível definir o diretório atual do Notes (Curdir) para o diretório temporário e usar apenas nomes de arquivo. Entretanto, configurar Curdir não é muito seguro, porque (1) você pode ter outros scripts executando em paralelo no mesmo processo e (2) esses scripts também estão configurando Curdir (ou presumindo que tem seu valor padrão).
  • Infelizmente, configurar a propriedade FilePath do conector do Notes não o faz procurar os arquivos esse diretório se o valor FILE não especificar um caminho.
  • Esse script também usa um metaconector Collapse/Expand, nesse caso, para converter de várias linhas relacionais para um único campo de diversos valores do Notes, Crimes.

Sincronização da vida real

Os scripts precedentes são bastante simples. Na vida real, os aplicativos frequentemente são mais complexos que apenas largar dados de um banco de dados para o outro. Mais comumente, desejamos sincronizar informações entre diferentes origens de dados.

É claro, se o movimento de dados for de uma via, é possível sincronizá-lo excluindo todos os dados no destino e então copiando tudo da origem -- também conhecida como técnica do programador preguiçoso. Em certos aplicativos, não há problema usar essa técnica, mas há vários fatores que podem tornar isso uma má ideia:

  • Cada vez mais, muitos bancos de dados de todos os tipos têm código de evento programado customizado que aciona quando os registros são adicionados, excluídos ou modificados. Excluir um registro e então adicionar um novo exatamente igual ao excluído pode acionar processamento desnecessário com resultados possivelmente desagradáveis.
  • Se o destino for o Lotus Notes, há várias desvantagens de realizar dump e recriar todos os documentos do Notes:
    • Os doclinks criados hoje não funcionarão amanhã.
    • Exclusões deixam para trás stubs de exclusão, que inflam o tamanho do banco de dados, aumentam a replicação e os tempos de indexação da visualização e geralmente prejudicam o desempenho, especialmente quando há 40 vezes mais stubs que documentos ativos.
    • Marcas não lidas não existem mais.
    • Servidores Domino, também, podem ter processamento baseado em evento, como complementos de API e agentes que executam em documentos novos e modificados.
  • Outros tipos de bancos de dados também podem sofrer déficits de desempenho devido a rotatividade desnecessária nos dados.

Para ajudá-lo a navegar nessas águas, o banco de dados de amostra também contém um agente de amostra que realiza uma sincronização simples com chave de uma via entre duas LCConnections. O agente "5. Replicar Piratas" inclui um mecanismo de replicação reutilizável que lê um registro por vez de dois conjuntos de resultados e compara as chaves e os valores de dados para decidir se há ou não uma diferença entre os registros e, se houver, se ela representa uma inserção, atualização ou exclusão. Então, o próximo registro é lido de um ou ambos os conjuntos de resultados conforme o adequado. Fica a seu critério alimentar esse mecanismo com dois conjuntos de resultados que são classificados de maneira idêntica, o que, para algumas combinações de conectores, pode exigir o uso de um metaconector Order. Depois de ter feito isso, o processo é automático (pelo menos para tipos de campo simples).

Fica a seu critério combinar essa técnica com qualquer manipulação de anexo do arquivo que possa precisar fazer. Mas embora você possa usar um objeto LCStream para comparar os dados binários dos dois anexos do arquivo para ver se eles são ou não iguais, é muito mais rápido comparar os registros de data e hora.


Conclusão

Este artigo descreveu como trabalhar com anexos de arquivo no LCLSX. Falamos um pouco sobre como o LCLSX manipula anexos de arquivo e então discutimos em detalhes o aplicativo de amostra incluído para demonstrar o processamento de anexo do arquivo. Concluímos com algumas observações sobre técnicas de sincronização do mundo real.

Esperamos que você considere este artigo útil. Se for o caso, sugerimos que faça o download da amostra fornecida e adapte-a às suas próprias necessidades e requisitos. Boa sorte!

Recursos

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Lotus
ArticleID=838437
ArticleTitle= Trabalhar com anexos de arquivo no LCLSX
publish-date=10012012