/// <summary> /// Procesa una exportación de una consulta a CSV /// </summary> internal bool Execute(SentenceExportPartitionedCsv sentence) { bool exported = false; using (BlockLogModel block = Processor.Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, $"Start exporting partitioned to {System.IO.Path.GetFileName(sentence.FileName)}")) { if (string.IsNullOrWhiteSpace(sentence.Command.Sql)) { block.Error("There is not command at export sentence"); } else { ProviderModel provider = Processor.GetProvider(sentence.Source); string baseFileName = Processor.Manager.Step.Project.GetFullFileName(sentence.FileName); if (provider == null) { block.Error($"Can't find the provider. Key: '{sentence.Source}'"); } else if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(baseFileName))) { block.Error($"Can't find the directory '{System.IO.Path.GetDirectoryName(baseFileName)}'"); } else { CommandModel command = Processor.ConvertProviderCommand(sentence.Command, out string error); if (!string.IsNullOrWhiteSpace(error)) { block.Error($"Error when convert export command. {error}"); } else { try { // Exporta los datos Export(provider, command, sentence, baseFileName, block); // Indica que se ha exportado correctamente exported = true; } catch (Exception exception) { block.Error($"Error when export '{sentence.FileName}'", exception); } } } } } // Devuelve el valor que indica si se ha exportado correctamente return(exported); }
/// <summary> /// Abre un archivo /// </summary> private CsvWriter OpenFile(SentenceExportPartitionedCsv sentence, List <ColumnModel> headers, string fileName) { CsvWriter writer = new CsvWriter(sentence.Definition); // Crea el directorio LibHelper.Files.HelperFiles.MakePath(System.IO.Path.GetDirectoryName(fileName)); // Abre el archivo writer.Open(fileName); // Escribe las cabeceras writer.WriteHeaders(GetHeaders(headers, sentence.Definition.TypedHeader)); // Devuelve el archivo return(writer); }
/// <summary> /// Exporta el resultado del comando /// </summary> private void Export(ProviderModel provider, CommandModel command, SentenceExportPartitionedCsv sentence, string baseFileName, BlockLogModel block) { using (IDataReader reader = provider.OpenReader(command, sentence.Timeout)) { long records = 0; List <ColumnModel> headers = GetColumns(reader); string partitionKey = string.Empty; CsvWriter writer = null; // Lee los registros y los va grabando en particiones while (reader.Read()) { string actualPartition = GetPartitionKey(sentence.Columns, sentence.PartitionSeparator, reader); // Cambia la partición if (!actualPartition.EqualsIgnoreCase(partitionKey)) { string fileName = GetFileName(baseFileName, sentence.PartitionSeparator, actualPartition); // Log block.Info($"Opening the file: {fileName}"); // Cierra el archivo si ya existía CloseFile(writer); // Abre un nuevo archivo writer = OpenFile(sentence, headers, fileName); // Cambia la clave de partición partitionKey = actualPartition; } // Añade la línea writer.WriteRow(GetValues(headers, reader)); // Lanza el evento de progreso if (++records % sentence.BatchSize == 0) { block.Progress("Copying", records, 0); } } // Cierra el archivo si estaba abierto CloseFile(writer); // Log block.Info($"Exported {records:#,##0} records"); } }
/// <summary> /// Carga una sentencia para exportar una serie de archivos CSV particionados /// </summary> private SentenceBase LoadSentenceExportPartitionedCsv(MLNode rootML) { SentenceExportPartitionedCsv sentence = new SentenceExportPartitionedCsv(); // Asigna las propiedades sentence.Source = rootML.Attributes[TagSource].Value; sentence.FileName = rootML.Attributes[TagFileName].Value; sentence.BatchSize = rootML.Attributes[TagBatchSize].Value.GetInt(BatchSizeDefault); sentence.Command = GetProviderCommand(rootML, TagLoad); // Carga la definición LoadDefinitionCsv(sentence.Definition, rootML); // Carga las columnas de partición foreach (MLNode nodeML in rootML.Nodes) { if (nodeML.Name == TagPartitionBy && !string.IsNullOrWhiteSpace(nodeML.Attributes[TagColumn].Value)) { sentence.Columns.Add(nodeML.Attributes[TagColumn].Value.TrimIgnoreNull()); } } // Devuelve la sentencia return(sentence); }