Skip to content

Commit

Permalink
Documentation improvements: Encryption (#494)
Browse files Browse the repository at this point in the history
  • Loading branch information
jescalada authored Jan 24, 2025
1 parent a6630c0 commit 36e8ccd
Show file tree
Hide file tree
Showing 13 changed files with 289 additions and 6 deletions.
2 changes: 1 addition & 1 deletion csharp/Arrow/FileReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace ParquetSharp.Arrow
{
/// <summary>
/// Reads Parquet files using the Arrow format
/// Reads Parquet files using the Arrow format.
/// </summary>
public class FileReader : IDisposable
{
Expand Down
43 changes: 43 additions & 0 deletions csharp/ColumnChunkMetaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

namespace ParquetSharp
{
/// <summary>
/// Represents the metadata for a column chunk.
/// </summary>
/// <remarks>
/// Provides access to the metadata for a column chunk and manages the associated native resources.
/// Because this class is a wrapper around C++ objects, it implements <see cref="IDisposable"/> to release resources predictably.
/// Make sure to call <see cref="Dispose"/> or use a `using` statement for proper cleanup.
/// </remarks>
public sealed class ColumnChunkMetaData : IDisposable
{
internal ColumnChunkMetaData(IntPtr handle)
Expand All @@ -15,8 +23,16 @@ public void Dispose()
_handle.Dispose();
}

/// <summary>
/// Get the compression codec used for the column chunk.
/// </summary>
/// <value>A <see cref="ParquetSharp.Compression"/> value representing the compression codec used for the column chunk.</value>
public Compression Compression => ExceptionInfo.Return<Compression>(_handle, ColumnChunkMetaData_Compression);

/// <summary>
/// Get the encryption metadata associated with the column.
/// </summary>
/// <value>A <see cref="ColumnCryptoMetaData"/> object representing the encryption metadata for the column, or <see langword="null"/> if no encryption metadata is available.</value>
public ColumnCryptoMetaData? CryptoMetadata
{
get
Expand All @@ -26,6 +42,10 @@ public ColumnCryptoMetaData? CryptoMetadata
}
}

/// <summary>
/// Get the encodings used for the column chunk.
/// </summary>
/// <value>An array of <see cref="Encoding"/> values representing the encodings used for the column chunk.</value>
public unsafe Encoding[] Encodings
{
get
Expand All @@ -43,12 +63,35 @@ public unsafe Encoding[] Encodings
}
}

/// <summary>
/// Get the offset of the column chunk in the file.
/// </summary>
public long FileOffset => ExceptionInfo.Return<long>(_handle, ColumnChunkMetaData_File_Offset);
/// <summary>
/// Whether the column chunk statistics are present in the metadata.
/// </summary>
public bool IsStatsSet => ExceptionInfo.Return<bool>(_handle, ColumnChunkMetaData_Is_Stats_Set);
/// <summary>
/// Get the total number of values in the column chunk.
/// </summary>
public long NumValues => ExceptionInfo.Return<long>(_handle, ColumnChunkMetaData_Num_Values);
/// <summary>
/// Get the total compressed size of the column chunk in bytes.
/// </summary>
public long TotalCompressedSize => ExceptionInfo.Return<long>(_handle, ColumnChunkMetaData_Total_Compressed_Size);
/// <summary>
/// Get the total uncompressed size of the column chunk in bytes.
/// </summary>
public long TotalUncompressedSize => ExceptionInfo.Return<long>(_handle, ColumnChunkMetaData_Total_Uncompressed_Size);
/// <summary>
/// Get the statistics for the column chunk.
/// </summary>
/// <value>A <see cref="ParquetSharp.Statistics"/> object representing the statistics for the column chunk, or <see langword="null"/> if no statistics are available.</value>
public Statistics? Statistics => Statistics.Create(ExceptionInfo.Return<IntPtr>(_handle, ColumnChunkMetaData_Statistics));
/// <summary>
/// Get the physical type of the column chunk.
/// </summary>
/// <value>A <see cref="PhysicalType"/> value representing the physical type of the column chunk.</value>
public PhysicalType Type => ExceptionInfo.Return<PhysicalType>(_handle, ColumnChunkMetaData_Type);

[DllImport(ParquetDll.Name)]
Expand Down
22 changes: 21 additions & 1 deletion csharp/ColumnCryptoMetaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
namespace ParquetSharp
{
/// <summary>
/// Metadata related to the encryption/decryption of a column.
/// Represents metadata related to the encryption and decryption of a Parquet column.
/// Provides access to encryption-specific properties for a column and manages the associated native resources.
/// </summary>
/// <remarks>
/// Because this class is a wrapper around C++ objects, it implements <see cref="IDisposable"/> to release resources predictably.
/// Make sure to call <see cref="Dispose"/> or use a `using` statement for proper cleanup.
/// </remarks>
public sealed class ColumnCryptoMetaData : IDisposable
{
internal ColumnCryptoMetaData(IntPtr handle)
Expand All @@ -19,8 +24,23 @@ public void Dispose()
_handle.Dispose();
}

/// <summary>
/// Get the path in the schema that specifies the column.
/// </summary>
/// <value>A <see cref="ColumnPath"/> that specifies the column's path in the schema.</value>
public ColumnPath ColumnPath => new ColumnPath(ExceptionInfo.Return<IntPtr>(_handle, ColumnCryptoMetaData_Path_In_Schema));

/// <summary>
/// Whether the column is encrypted with the footer key.
/// </summary>
/// <value>
/// <see langword="true"/> if the column is encrypted with the footer key; otherwise, <see langword="false"/>.
/// </value>
public bool EncryptedWithFooterKey => ExceptionInfo.Return<bool>(_handle, ColumnCryptoMetaData_Encrypted_With_Footer_Key);

/// <summary>
/// Get the key metadata associated with the column.
/// </summary>
public string KeyMetadata => ExceptionInfo.ReturnString(_handle, ColumnCryptoMetaData_Key_Metadata);

[DllImport(ParquetDll.Name)]
Expand Down
6 changes: 6 additions & 0 deletions csharp/ColumnDecryptionProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ public void Dispose()
Handle.Dispose();
}

/// <summary>
/// Get the path of the column to decrypt.
/// </summary>
public string ColumnPath => ExceptionInfo.ReturnString(Handle, ColumnDecryptionProperties_Column_Path, ColumnDecryptionProperties_Column_Path_Free);
/// <summary>
/// Get the key used to decrypt the column.
/// </summary>
public byte[] Key => ExceptionInfo.Return<AesKey>(Handle, ColumnDecryptionProperties_Key).ToBytes();

public ColumnDecryptionProperties DeepClone() => new ColumnDecryptionProperties(ExceptionInfo.Return<IntPtr>(Handle, ColumnDecryptionProperties_Deep_Clone));
Expand Down
20 changes: 19 additions & 1 deletion csharp/ColumnDecryptionPropertiesBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,24 @@
namespace ParquetSharp
{
/// <summary>
/// Builder pattern for ColumnDecryptionProperties.
/// Builder pattern for creating and configuring <see cref="ColumnDecryptionProperties"/> objects.
/// Provides a fluent API for setting the decryption properties for a column in a Parquet file.
/// </summary>
public sealed class ColumnDecryptionPropertiesBuilder : IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="ColumnDecryptionPropertiesBuilder"/> class for a column specified by name.
/// </summary>
/// <param name="columnName">The name of the column to decrypt.</param>
public ColumnDecryptionPropertiesBuilder(string columnName)
: this(Make(columnName))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="ColumnDecryptionPropertiesBuilder"/> class for a column specified by path.
/// </summary>
/// <param name="columnPath">The <see cref="ColumnPath"/> object representing the column to decrypt.</param>
public ColumnDecryptionPropertiesBuilder(ColumnPath columnPath)
: this(Make(columnPath))
{
Expand All @@ -29,6 +38,11 @@ public void Dispose()
_handle.Dispose();
}

/// <summary>
/// Set the decryption key for the column.
/// </summary>
/// <param name="key">A byte array containing the AES decryption key.</param>
/// <returns>This builder instance.</returns>
public ColumnDecryptionPropertiesBuilder Key(byte[] key)
{
var aesKey = new AesKey(key);
Expand All @@ -37,6 +51,10 @@ public ColumnDecryptionPropertiesBuilder Key(byte[] key)
return this;
}

/// <summary>
/// Build the <see cref="ColumnDecryptionProperties"/> object.
/// </summary>
/// <returns>The configured <see cref="ColumnDecryptionProperties"/> object.</returns>
public ColumnDecryptionProperties Build() => new ColumnDecryptionProperties(ExceptionInfo.Return<IntPtr>(_handle, ColumnDecryptionPropertiesBuilder_Build));

private static IntPtr Make(string columnName)
Expand Down
30 changes: 29 additions & 1 deletion csharp/ColumnEncryptionPropertiesBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,24 @@
namespace ParquetSharp
{
/// <summary>
/// Builder pattern for ColumnEncryptionProperties.
/// Builder pattern for creating and configuring <see cref="ColumnEncryptionProperties"/> objects.
/// Provides a fluent API for setting the encryption properties for a column in a Parquet file.
/// </summary>
public sealed class ColumnEncryptionPropertiesBuilder : IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="ColumnEncryptionPropertiesBuilder"/> class for a column specified by name.
/// </summary>
/// <param name="columnName">The name of the column to encrypt.</param>
public ColumnEncryptionPropertiesBuilder(string columnName)
: this(Make(columnName))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="ColumnEncryptionPropertiesBuilder"/> class for a column specified by path.
/// </summary>
/// <param name="columnPath">The <see cref="ColumnPath"/> object representing the column to encrypt.</param>
public ColumnEncryptionPropertiesBuilder(ColumnPath columnPath)
: this(Make(columnPath))
{
Expand All @@ -29,6 +38,11 @@ public void Dispose()
_handle.Dispose();
}

/// <summary>
/// Set the encryption key for the column.
/// </summary>
/// <param name="key">A byte array containing the AES encryption key.</param>
/// <returns>This builder instance.</returns>
public ColumnEncryptionPropertiesBuilder Key(byte[] key)
{
var aesKey = new AesKey(key);
Expand All @@ -37,20 +51,34 @@ public ColumnEncryptionPropertiesBuilder Key(byte[] key)
return this;
}

/// <summary>
/// Set the metadata associated with the encryption key for the column.
/// </summary>
/// <param name="keyMetadata">A string containing the metadata associated with the encryption key.</param>
/// <returns>This builder instance.</returns>
public ColumnEncryptionPropertiesBuilder KeyMetadata(string keyMetadata)
{
ExceptionInfo.Check(ColumnEncryptionPropertiesBuilder_Key_Metadata(_handle.IntPtr, keyMetadata));
GC.KeepAlive(_handle);
return this;
}

/// <summary>
/// Set the key ID associated with the column's encryption key.
/// </summary>
/// <param name="keyId">An identifier for the encryption key.</param>
/// <returns>This builder instance.</returns>
public ColumnEncryptionPropertiesBuilder KeyId(string keyId)
{
ExceptionInfo.Check(ColumnEncryptionPropertiesBuilder_Key_Id(_handle.IntPtr, keyId));
GC.KeepAlive(_handle);
return this;
}

/// <summary>
/// Builds the <see cref="ColumnEncryptionProperties"/> object.
/// </summary>
/// <returns>The configured <see cref="ColumnEncryptionProperties"/> object.</returns>
public ColumnEncryptionProperties Build() => new ColumnEncryptionProperties(ExceptionInfo.Return<IntPtr>(_handle, ColumnEncryptionPropertiesBuilder_Build));

private static IntPtr Make(string columnName)
Expand Down
43 changes: 42 additions & 1 deletion csharp/FileDecryptionPropertiesBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
namespace ParquetSharp
{
/// <summary>
/// Builder pattern for FileDecryptionProperties.
/// Builder pattern for creating and configuring a <see cref="FileDecryptionProperties"/> object.
/// Provides a fluent API for setting the decryption properties (footer key, encryption algorithm, etc.) for a Parquet file.
/// </summary>
public sealed class FileDecryptionPropertiesBuilder : IDisposable
{
/// <summary>
/// Create a new <see cref="FileDecryptionPropertiesBuilder"/>.
/// </summary>
public FileDecryptionPropertiesBuilder()
{
ExceptionInfo.Check(FileDecryptionPropertiesBuilder_Create(out var handle));
Expand All @@ -20,6 +24,11 @@ public void Dispose()
_handle.Dispose();
}

/// <summary>
/// Set the footer key used to decrypt the file.
/// </summary>
/// <param name="footerKey">An array of bytes used to decrypt the footer.</param>
/// <returns>This builder instance.</returns>
public FileDecryptionPropertiesBuilder FooterKey(byte[] footerKey)
{
var footerAesKey = new AesKey(footerKey);
Expand All @@ -28,6 +37,11 @@ public FileDecryptionPropertiesBuilder FooterKey(byte[] footerKey)
return this;
}

/// <summary>
/// Set the keys used to decrypt the columns.
/// </summary>
/// <param name="columnDecryptionProperties">An array of <see cref="ColumnDecryptionProperties"/> objects.</param>
/// <returns>This builder instance.</returns>
public FileDecryptionPropertiesBuilder ColumnKeys(ColumnDecryptionProperties[] columnDecryptionProperties)
{
var handles = columnDecryptionProperties.Select(p => p.Handle.IntPtr).ToArray();
Expand All @@ -37,6 +51,11 @@ public FileDecryptionPropertiesBuilder ColumnKeys(ColumnDecryptionProperties[] c
return this;
}

/// <summary>
/// Set the prefix verifier used to verify the additional authenticated data (AAD) prefix.
/// </summary>
/// <param name="aadPrefixVerifier">An <see cref="ParquetSharp.AadPrefixVerifier"/> object that provides a callback to verify the AAD prefix.</param>
/// <returns>This builder instance.</returns>
public FileDecryptionPropertiesBuilder AadPrefixVerifier(AadPrefixVerifier aadPrefixVerifier)
{
var gcHandle = aadPrefixVerifier?.CreateGcHandle() ?? IntPtr.Zero;
Expand All @@ -62,6 +81,11 @@ public FileDecryptionPropertiesBuilder AadPrefixVerifier(AadPrefixVerifier aadPr
return this;
}

/// <summary>
/// Set the key retriever used to retrieve the decryption keys.
/// </summary>
/// <param name="keyRetriever">A <see cref="DecryptionKeyRetriever"/> object that provides a callback to retrieve the decryption keys.</param>
/// <returns>This builder instance.</returns>
public FileDecryptionPropertiesBuilder KeyRetriever(DecryptionKeyRetriever keyRetriever)
{
var gcHandle = keyRetriever?.CreateGcHandle() ?? IntPtr.Zero;
Expand All @@ -87,27 +111,44 @@ public FileDecryptionPropertiesBuilder KeyRetriever(DecryptionKeyRetriever keyRe
return this;
}

/// <summary>
/// Disable footer signature verification.
/// </summary>
/// <returns>This builder instance.</returns>
public FileDecryptionPropertiesBuilder DisableFooterSignatureVerification()
{
ExceptionInfo.Check(FileDecryptionPropertiesBuilder_Disable_Footer_Signature_Verification(_handle.IntPtr));
GC.KeepAlive(_handle);
return this;
}

/// <summary>
/// Set the additional authenticated data (AAD) prefix.
/// </summary>
/// <param name="aadPrefix">A string representing the AAD prefix.</param>
/// <returns>This builder instance.</returns>
public FileDecryptionPropertiesBuilder AadPrefix(string aadPrefix)
{
ExceptionInfo.Check(FileDecryptionPropertiesBuilder_Aad_Prefix(_handle.IntPtr, aadPrefix));
GC.KeepAlive(_handle);
return this;
}

/// <summary>
/// Allow plaintext (unencrypted) files.
/// </summary>
/// <returns>This builder instance.</returns>
public FileDecryptionPropertiesBuilder PlaintextFilesAllowed()
{
ExceptionInfo.Check(FileDecryptionPropertiesBuilder_Plaintext_Files_Allowed(_handle.IntPtr));
GC.KeepAlive(_handle);
return this;
}

/// <summary>
/// Build the <see cref="FileDecryptionProperties"/> object.
/// </summary>
/// <returns>A new <see cref="FileDecryptionProperties"/> object with the configured decryption properties.</returns>
public FileDecryptionProperties Build() => new FileDecryptionProperties(ExceptionInfo.Return<IntPtr>(_handle, FileDecryptionPropertiesBuilder_Build));

[DllImport(ParquetDll.Name)]
Expand Down
Loading

0 comments on commit 36e8ccd

Please sign in to comment.