#ifndef INDICE_SECUNDARIO_H #define INDICE_SECUNDARIO_H #include #include #include #include #include #include template class Indice_Secundario { public: Indice_Secundario(String arquivo, String campo, String campo_cp, TIPO tcampo, TIPO tcampo_cp, String tipo_estrutura) { this->arquivo = arquivo; this->arquivo_li = "LI_"; this->arquivo_li += arquivo; this->campo = campo; this->campo_cp = campo_cp; this->tcampo = tcampo; this->tcampo_cp = tcampo_cp; this->tipo_estrutura = tipo_estrutura; this->indice = new t_class3(this->arquivo.Texto(),this->campo.Texto(),"POSICAO",tcampo,LONG); this->lista_invertida = new Lista_Invertida(this->arquivo_li.Texto(),this->campo_cp.Texto(),this->tcampo_cp); this->delimitador = ';'; this->delimitador_linha = '\n'; } virtual ~Indice_Secundario() { if (indice != NULL) delete indice; if (lista_invertida != NULL) delete lista_invertida; }; /** * Apaga: apaga o indice da memoria e o arquivo */ void Apaga() { if (indice != NULL) indice->Apaga(); if (lista_invertida != NULL) lista_invertida->Apaga(); }; /** * Insere: insere valor e valor da chave primaria neste indice secundario *@param valor do campo *@param valor_cp da chave primaria */ void Insere(t_class1 valor, t_class2 valor_cp) { long posicao, nova_posicao; if (indice->Procura(valor,&posicao) == true) { // Ja existe, so acrescenta a lista invertida nova_posicao = lista_invertida->Insere(valor_cp, posicao); indice->Altera(valor,posicao, nova_posicao); } else { nova_posicao = lista_invertida->Insere(valor_cp, -1); indice->Insere(valor,nova_posicao); } } /** * Procura: procura por determinado valor e retorna a lista de chaves primarias *@param valor a ser procurado *@return lista ligada de chaves primarias ou NULL, caso nao achou *OBS: Memória Dinâminca! Liberar após o uso. */ Lista_Simples *Procura(t_class1 valor) { Lista_Simples *resultado = NULL; long posicao=0; if (indice->Procura(valor,&posicao) == true) { resultado = lista_invertida->Pega_Lista(posicao); } return resultado; } /** * Le: lê o arquivo de índice e o de lista invertida *@return 0=ok, -1 = não pode ler o arquivo, -2 = formato incorreto, -3 = dados não conferem com os pedidos(campo e referencia), -4=o arquivo de indice foi gerado para outra estrutura que nao a atual(Ex. foi escrito para lista e vai ser lido por arvore bin) */ /** * Le: lê o 'arquivo' que relaciona 'campo' com 'referencia', onde 'campo' é o nome do campo do banco de dados a qual este índice trata. Os delimitadores podem ser escolhidos, mas os padrões devem bastar. *@return 0=ok, -1 = não pode ler o arquivo, -2 = formato incorreto, -3 = dados não conferem com os pedidos(campo e referencia), -4=o arquivo de indice foi gerado para outra estrutura que nao a atual(Ex. foi escrito para lista e vai ser lido por arvore bin) */ int Le() { int erro=0; erro=indice->Le(); erro=10*lista_invertida->Le(); return erro; } /** * Escreve: Escreve o arquivo de Indice */ bool Escreve() { return Escreve(arquivo.Texto(), arquivo_li.Texto(),delimitador,delimitador_linha); } bool Escreve(String arquivo, String arquivo_li, char delimitador, char delimitador_linha) { return indice->Escreve(arquivo,delimitador,delimitador_linha); } protected: t_class3 *indice; Lista_Invertida *lista_invertida; String arquivo_li; String arquivo; String campo; String campo_cp; TIPO tcampo; TIPO tcampo_cp; String tipo_estrutura; char delimitador; char delimitador_linha; }; #endif