예제 #1
0
        /// <summary>
        ///		Procesa una exportación de una consulta a un archivo parquet
        /// </summary>
        public long Write(System.Data.IDataReader reader, int rowGroupSize = 45_000)
        {
            long records = 0;
            List <(string, FieldType)> columns = GetColumnsSchema(reader);

            // Obtiene la información de zona horario
            try
            {
                _timeZoneCentral = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
            }
            catch
            {
                _timeZoneCentral = TimeZoneInfo.Local;
            }
            // Escribe en el archivo
            using (System.IO.FileStream stream = System.IO.File.Open(FileName, System.IO.FileMode.Create, System.IO.FileAccess.Write))
            {
                Schema schema = GetSchema(columns);

                using (ParquetWriter writer = new ParquetWriter(schema, stream))
                {
                    Table table = new Table(schema);

                    // Establece el método de compresión
                    //? No asigna el nivel de compresión: deja el predeterminado para el método
                    writer.CompressionMethod = CompressionMethod.Snappy;
                    // Carga los registros y los va añadiendo a la lista para meterlos en un grupo de filas
                    while (reader.Read())
                    {
                        // Escribe la tabla en el archivo si se ha superado el número máximo de filas
                        if (table.Count >= rowGroupSize)
                        {
                            // Escribe la tabla en un grupo de filas
                            FlushRowGroup(writer, table);
                            // Limpia la tabla
                            table.Clear();
                        }
                        // Añade los datos del registro a la lista
                        table.Add(ConvertData(reader, columns));
                        // Lanza el evento de progreso
                        if (++records % NotifyAfter == 0)
                        {
                            WriteBlock?.Invoke(this, new EventArguments.AffectedEvntArgs(records));
                        }
                    }
                    // Graba las últimas filas
                    FlushRowGroup(writer, table);
                }
            }
            // Devuelve el número de registros escritos
            return(records);
        }