diff --git a/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs b/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs index b9e806d..560d321 100644 --- a/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs +++ b/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs @@ -45,8 +45,9 @@ using System.Runtime.InteropServices; // 1.9.3.0 2015.08.11. Dependence added from Collections to Isam dll for configsets. // 1.9.3.2 2015.09.02. Some bug fixes; go back to Framework 4.0 // 1.9.3.3 2016.03.01. Some bug and perf fixes. -[assembly: AssemblyVersion("1.9.3.3")] -[assembly: AssemblyFileVersion("1.9.3.3")] +// 1.9.4 2016.06.28. Some bug fixes. +[assembly: AssemblyVersion("1.9.4")] +[assembly: AssemblyFileVersion("1.9.4")] #if STRONG_NAMED [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("EsentCollectionsTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] diff --git a/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs b/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs index 18b3db9..4c3b842 100644 --- a/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs +++ b/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs @@ -27,7 +27,7 @@ namespace Microsoft.Database.Isam.Config /// /// The exclusive upper bound on JET_param*. /// - internal const int ParamMaxValueInvalid = 195; // should be equal to JET_paramMaxValueInvalid + internal const int ParamMaxValueInvalid = 196; // should be equal to JET_paramMaxValueInvalid /// /// Fills the param table from auto-generated code. @@ -156,6 +156,7 @@ namespace Microsoft.Database.Isam.Config DatabaseConfig.ParamTable[186] = new ParamDef(186, true, typeof(string)); // JET_paramProcessFriendlyName DatabaseConfig.ParamTable[187] = new ParamDef(187, false, typeof(IntPtr)); // JET_paramDurableCommitCallback DatabaseConfig.ParamTable[189] = new ParamDef(189, false, typeof(string)); // JET_paramConfigStoreSpec + DatabaseConfig.ParamTable[193] = new ParamDef(193, false, typeof(int)); // JET_paramPersistedLostFlushDetection DatabaseConfig.ParamTable[194] = new ParamDef(194, false, typeof(int)); // JET_paramEngineFormatVersion } @@ -1496,6 +1497,15 @@ namespace Microsoft.Database.Isam.Config set { this.SetParam(189, value); } } + /// + /// Configures persisted lost flush detection for databases while attached to an instance. + /// + public int PersistedLostFlushDetection + { + get { return this.GetParam(193); } + set { this.SetParam(193, value); } + } + /// /// Engine format version - specifies the maximum format version the engine should allow, ensuring no format features are used beyond this (allowing the DB / logs to be forward compatible). /// diff --git a/Src/Microsoft.Isam.Esent.Interop/BytesColumnValue.cs b/Src/Microsoft.Isam.Esent.Interop/BytesColumnValue.cs index 6378945..384564e 100644 --- a/Src/Microsoft.Isam.Esent.Interop/BytesColumnValue.cs +++ b/Src/Microsoft.Isam.Esent.Interop/BytesColumnValue.cs @@ -14,6 +14,11 @@ namespace Microsoft.Isam.Esent.Interop /// public class BytesColumnValue : ColumnValue { + /// + /// Internal value. + /// + private byte[] internalValue; + /// /// Gets the last set or retrieved value of the column. The /// value is returned as a generic object. @@ -28,7 +33,19 @@ namespace Microsoft.Isam.Esent.Interop /// Gets or sets the value of the column. Use to update a /// record with the column value. /// - public byte[] Value { get; set; } + public byte[] Value + { + get + { + return this.internalValue; + } + + set + { + this.internalValue = value; + this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success; + } + } /// /// Gets the byte length of a column value, which is zero if column is null, otherwise @@ -110,8 +127,9 @@ namespace Microsoft.Isam.Esent.Interop } else { - this.Value = new byte[count]; - Buffer.BlockCopy(value, startIndex, this.Value, 0, count); + var copiedValue = new byte[count]; + Buffer.BlockCopy(value, startIndex, copiedValue, 0, count); + this.Value = copiedValue; } } } diff --git a/Src/Microsoft.Isam.Esent.Interop/ColumnValue.cs b/Src/Microsoft.Isam.Esent.Interop/ColumnValue.cs index e4c5bef..210a758 100644 --- a/Src/Microsoft.Isam.Esent.Interop/ColumnValue.cs +++ b/Src/Microsoft.Isam.Esent.Interop/ColumnValue.cs @@ -9,12 +9,18 @@ namespace Microsoft.Isam.Esent.Interop using System; using System.Collections.Generic; using System.Diagnostics; + using System.Globalization; /// /// Base class for objects that represent a column value to be set. /// - public abstract class ColumnValue + public abstract partial class ColumnValue { + /// + /// Internal grbit. + /// + private RetrieveColumnGrbit grbit; + /// /// Initializes a new instance of the ColumnValue class. /// @@ -42,7 +48,19 @@ namespace Microsoft.Isam.Esent.Interop /// /// Gets or sets column retrieval options. /// - public RetrieveColumnGrbit RetrieveGrbit { get; set; } + public RetrieveColumnGrbit RetrieveGrbit + { + get + { + return this.grbit; + } + + set + { + this.ValidateRetrieveGrbit(value); + this.grbit = value; + } + } /// /// Gets or sets the column itag sequence. @@ -268,6 +286,19 @@ namespace Microsoft.Isam.Esent.Interop /// The error returned from ESENT. protected abstract void GetValueFromBytes(byte[] value, int startIndex, int count, int err); + /// + /// Validation for the requested retrieve options for the column. + /// + /// The retrieve options to validate. + protected virtual void ValidateRetrieveGrbit(RetrieveColumnGrbit grbit) + { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + } + /// /// Retrieve the value for columns whose buffers were truncated. /// @@ -302,6 +333,17 @@ namespace Microsoft.Isam.Esent.Interop retinfo); } + if (JET_wrn.BufferTruncated == (JET_wrn)err) + { + string error = string.Format( + CultureInfo.CurrentCulture, + "Column size changed from {0} to {1}. The record was probably updated by another thread.", + buffer.Length, + actualSize); + Trace.TraceError(error); + throw new InvalidOperationException(error); + } + // Throw errors, but put warnings in the structure Api.Check(err); columnValues[i].Error = (JET_wrn)err; diff --git a/Src/Microsoft.Isam.Esent.Interop/ColumnValueOfStruct.cs b/Src/Microsoft.Isam.Esent.Interop/ColumnValueOfStruct.cs index 739310f..55aa557 100644 --- a/Src/Microsoft.Isam.Esent.Interop/ColumnValueOfStruct.cs +++ b/Src/Microsoft.Isam.Esent.Interop/ColumnValueOfStruct.cs @@ -14,6 +14,11 @@ namespace Microsoft.Isam.Esent.Interop /// Type to set. public abstract class ColumnValueOfStruct : ColumnValue where T : struct, IEquatable { + /// + /// Internal value. + /// + private T? internalValue; + /// /// Gets the last set or retrieved value of the column. The /// value is returned as a generic object. @@ -29,7 +34,19 @@ namespace Microsoft.Isam.Esent.Interop /// /// Gets or sets the value in the struct. /// - public T? Value { get; set; } + public T? Value + { + get + { + return this.internalValue; + } + + set + { + this.internalValue = value; + this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success; + } + } /// /// Gets the byte length of a column value, which is zero if column is null, otherwise diff --git a/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs b/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs index c970035..b550384 100644 --- a/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs +++ b/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs @@ -1342,6 +1342,38 @@ namespace Microsoft.Isam.Esent.Interop #endif } + /// + /// Base class for JET_err.BadLineCount exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentBadLineCountException : EsentCorruptionException + { + /// + /// Initializes a new instance of the EsentBadLineCountException class. + /// + public EsentBadLineCountException() : + base("Number of lines on the page is too few compared to the line being operated on", JET_err.BadLineCount) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentBadLineCountException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentBadLineCountException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + /// /// Base class for JET_err.KeyTooBig exceptions. /// @@ -1502,6 +1534,102 @@ namespace Microsoft.Isam.Esent.Interop #endif } + /// + /// Base class for JET_err.InvalidColumnReference exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentInvalidColumnReferenceException : EsentStateException + { + /// + /// Initializes a new instance of the EsentInvalidColumnReferenceException class. + /// + public EsentInvalidColumnReferenceException() : + base("Column reference is invalid", JET_err.InvalidColumnReference) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentInvalidColumnReferenceException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentInvalidColumnReferenceException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + + /// + /// Base class for JET_err.StaleColumnReference exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentStaleColumnReferenceException : EsentStateException + { + /// + /// Initializes a new instance of the EsentStaleColumnReferenceException class. + /// + public EsentStaleColumnReferenceException() : + base("Column reference is stale", JET_err.StaleColumnReference) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentStaleColumnReferenceException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentStaleColumnReferenceException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + + /// + /// Base class for JET_err.CompressionIntegrityCheckFailed exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentCompressionIntegrityCheckFailedException : EsentCorruptionException + { + /// + /// Initializes a new instance of the EsentCompressionIntegrityCheckFailedException class. + /// + public EsentCompressionIntegrityCheckFailedException() : + base("A compression integrity check failed. Decompressing data failed the integrity checksum indicating a data corruption in the compress/decompress pipeline.", JET_err.CompressionIntegrityCheckFailed) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentCompressionIntegrityCheckFailedException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentCompressionIntegrityCheckFailedException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + /// /// Base class for JET_err.InvalidLoggedOperation exceptions. /// @@ -3870,6 +3998,38 @@ namespace Microsoft.Isam.Esent.Interop #endif } + /// + /// Base class for JET_err.PageInitializedMismatch exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentPageInitializedMismatchException : EsentCorruptionException + { + /// + /// Initializes a new instance of the EsentPageInitializedMismatchException class. + /// + public EsentPageInitializedMismatchException() : + base("Database divergence mismatch. Page was uninitialized on remote node, but initialized on local node.", JET_err.PageInitializedMismatch) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentPageInitializedMismatchException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentPageInitializedMismatchException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + /// /// Base class for JET_err.UnicodeTranslationBufferTooSmall exceptions. /// @@ -10092,7 +10252,7 @@ namespace Microsoft.Isam.Esent.Interop /// Initializes a new instance of the EsentColumnCannotBeEncryptedException class. /// public EsentColumnCannotBeEncryptedException() : - base("Only JET_coltypLongText and JET_coltypLongBinary columns can be encrypted", JET_err.ColumnCannotBeEncrypted) + base("Only JET_coltypLongText and JET_coltypLongBinary columns without default values can be encrypted", JET_err.ColumnCannotBeEncrypted) { } @@ -12926,6 +13086,8 @@ namespace Microsoft.Isam.Esent.Interop return new EsentDatabaseLeakInSpaceException(); case JET_err.BadEmptyPage: return new EsentBadEmptyPageException(); + case JET_err.BadLineCount: + return new EsentBadLineCountException(); case JET_err.KeyTooBig: return new EsentKeyTooBigException(); case JET_err.CannotSeparateIntrinsicLV: @@ -12936,6 +13098,12 @@ namespace Microsoft.Isam.Esent.Interop return new EsentMustBeSeparateLongValueException(); case JET_err.InvalidPreread: return new EsentInvalidPrereadException(); + case JET_err.InvalidColumnReference: + return new EsentInvalidColumnReferenceException(); + case JET_err.StaleColumnReference: + return new EsentStaleColumnReferenceException(); + case JET_err.CompressionIntegrityCheckFailed: + return new EsentCompressionIntegrityCheckFailedException(); case JET_err.InvalidLoggedOperation: return new EsentInvalidLoggedOperationException(); case JET_err.LogFileCorrupt: @@ -13084,6 +13252,8 @@ namespace Microsoft.Isam.Esent.Interop return new EsentCommittedLogFileCorruptException(); case JET_err.LogSequenceChecksumMismatch: return new EsentLogSequenceChecksumMismatchException(); + case JET_err.PageInitializedMismatch: + return new EsentPageInitializedMismatchException(); case JET_err.UnicodeTranslationBufferTooSmall: return new EsentUnicodeTranslationBufferTooSmallException(); case JET_err.UnicodeTranslationFail: diff --git a/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs b/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs index 09d0ec9..1298b41 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs @@ -53,8 +53,9 @@ using System.Runtime.InteropServices; // 1.9.3.0 2015.08.11. Dependence added from Collections to Isam dll for configsets. // 1.9.3.2 2015.09.02. Some bug fixes; go back to Framework 4.0 // 1.9.3.3 2016.03.01. Some bug and perf fixes. -[assembly: AssemblyVersion("1.9.3.3")] -[assembly: AssemblyFileVersion("1.9.3.3")] +// 1.9.4 2016.06.28. Some bug fixes. +[assembly: AssemblyVersion("1.9.4")] +[assembly: AssemblyFileVersion("1.9.4")] #if STRONG_NAMED [assembly: InternalsVisibleTo("EsentInteropWsaTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] diff --git a/Src/Microsoft.Isam.Esent.Interop/Esent/EsentJetApi.cs b/Src/Microsoft.Isam.Esent.Interop/Esent/EsentJetApi.cs index 0273ce5..0c160c6 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Esent/EsentJetApi.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Esent/EsentJetApi.cs @@ -41,6 +41,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation const int Windows7BuildNumber = 7000; // includes beta as well as RTM (RTM is 7600) const int Windows8BuildNumber = 8000; // includes beta as well as RTM (RTM is 9200) const int Windows81BuildNumber = 9300; // includes beta as well as RTM (RTM is 9600) + const int Windows10BuildNumber = 9900; // includes beta as well as RTM (RTM is TBD) // Create new capabilities, set as all false. This will allow // us to call into Esent. @@ -95,6 +96,12 @@ namespace Microsoft.Isam.Esent.Interop.Implementation Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 8.1 features"); this.Capabilities.SupportsWindows81Features = true; } + + if (buildNumber >= Windows10BuildNumber) + { + Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 10 features"); + this.Capabilities.SupportsWindows10Features = true; + } } /// diff --git a/Src/Microsoft.Isam.Esent.Interop/JetApi.cs b/Src/Microsoft.Isam.Esent.Interop/JetApi.cs index a65a7db..c8f233b 100644 --- a/Src/Microsoft.Isam.Esent.Interop/JetApi.cs +++ b/Src/Microsoft.Isam.Esent.Interop/JetApi.cs @@ -944,9 +944,17 @@ namespace Microsoft.Isam.Esent.Interop.Implementation JET_DbInfo infoLevel) { TraceFunctionCall("JetGetDatabaseInfo"); - int err; + int err = (int)JET_err.Success; + dbinfomisc = null; - if (this.Capabilities.SupportsWindows7Features) + bool notYetPublishedSupported = false; + this.NotYetPublishedGetDbinfomisc(sesid, dbid, ref dbinfomisc, infoLevel, ref notYetPublishedSupported, ref err); + + if (notYetPublishedSupported) + { + // The not-yet-published function in the other file set the 'ref' parameters. + } + else if (this.Capabilities.SupportsWindows7Features) { NATIVE_DBINFOMISC4 native; err = Err(NativeMethods.JetGetDatabaseInfoW( @@ -5518,7 +5526,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation CheckNotNegative(dataSize, sizeArgumentName); CheckNotNegative(dataOffset, offsetArgumentName); - if ((null == data && 0 != dataOffset) || (null != data && dataOffset >= data.Count)) + if ((null == data && 0 != dataOffset) || (null != data && dataOffset > data.Count)) { Trace.WriteLineIf(TraceSwitch.TraceError, "CheckDataSize failed"); throw new ArgumentOutOfRangeException( @@ -6403,6 +6411,26 @@ namespace Microsoft.Isam.Esent.Interop.Implementation ref bool notYetPublishedSupported, ref int err); -#endregion + /// + /// Provides a hook to allow population of additional fields in + /// a different file. These additonal fields are not yet published + /// on MSDN. + /// + /// The session to use. + /// The database identifier. + /// The output structure to populate. + /// Specifies which information to retrieve. + /// Whether the additional fields specified by in + /// are populated. + /// The error code returned. + partial void NotYetPublishedGetDbinfomisc( + JET_SESID sesid, + JET_DBID dbid, + ref JET_DBINFOMISC dbinfomisc, + JET_DbInfo infoLevel, + ref bool notYetPublishedSupported, + ref int err); + + #endregion } } diff --git a/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs b/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs index b074aa1..2bbab12 100644 --- a/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs +++ b/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs @@ -184,6 +184,12 @@ namespace Microsoft.Isam.Esent.Interop public static int? RetrieveColumnSize( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, int itagSequence, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + var retinfo = new JET_RETINFO { itagSequence = itagSequence }; int dataSize; JET_wrn wrn = JetRetrieveColumn( @@ -250,7 +256,7 @@ namespace Microsoft.Isam.Esent.Interop data = new byte[dataSize]; wrn = JetRetrieveColumn( sesid, tableid, columnid, data, data.Length, out dataSize, grbit, retinfo); - if (JET_wrn.Success != wrn) + if (JET_wrn.BufferTruncated == wrn) { string error = string.Format( CultureInfo.CurrentCulture, @@ -417,6 +423,12 @@ namespace Microsoft.Isam.Esent.Interop public static short? RetrieveColumnAsInt16( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(short); @@ -454,6 +466,12 @@ namespace Microsoft.Isam.Esent.Interop public static int? RetrieveColumnAsInt32( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(int); @@ -491,6 +509,12 @@ namespace Microsoft.Isam.Esent.Interop public static long? RetrieveColumnAsInt64( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(long); @@ -528,6 +552,12 @@ namespace Microsoft.Isam.Esent.Interop public static float? RetrieveColumnAsFloat( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(float); @@ -565,6 +595,12 @@ namespace Microsoft.Isam.Esent.Interop public static double? RetrieveColumnAsDouble( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(double); @@ -636,6 +672,12 @@ namespace Microsoft.Isam.Esent.Interop public static byte? RetrieveColumnAsByte( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(byte); @@ -673,6 +715,12 @@ namespace Microsoft.Isam.Esent.Interop public static Guid? RetrieveColumnAsGuid( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = 16; @@ -747,6 +795,12 @@ namespace Microsoft.Isam.Esent.Interop public static ushort? RetrieveColumnAsUInt16( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(ushort); @@ -786,6 +840,12 @@ namespace Microsoft.Isam.Esent.Interop public static uint? RetrieveColumnAsUInt32( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(uint); @@ -825,6 +885,12 @@ namespace Microsoft.Isam.Esent.Interop public static ulong? RetrieveColumnAsUInt64( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + unsafe { const int DataSize = sizeof(ulong); @@ -861,6 +927,12 @@ namespace Microsoft.Isam.Esent.Interop [SuppressMessage("Exchange.Security", "EX0043:DoNotUseBinarySoapFormatter", Justification = "Suppress warning in current code base.The usage has already been verified.")] public static object DeserializeObjectFromColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + // We cannot support this request when there is no way to indicate that a column reference is returned. + if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord + { + throw new EsentInvalidGrbitException(); + } + int actualSize; if (JET_wrn.ColumnNull == Api.JetRetrieveColumn(sesid, tableid, columnid, null, 0, out actualSize, grbit, null)) { @@ -1008,6 +1080,8 @@ namespace Microsoft.Isam.Esent.Interop /// The string retrieved from the column. private static unsafe string RetrieveUnicodeString(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, RetrieveColumnGrbit grbit) { + Debug.Assert((grbit & (RetrieveColumnGrbit)0x00020000) == 0, "UnpublishedGrbits.RetrieveAsRefIfNotInRecord is not supported."); + // 512 Unicode characters (1kb on stack) const int BufferSize = 512; char* buffer = stackalloc char[BufferSize]; diff --git a/Src/Microsoft.Isam.Esent.Interop/Settings.StyleCop b/Src/Microsoft.Isam.Esent.Interop/Settings.StyleCop index f9f3c63..87f5222 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Settings.StyleCop +++ b/Src/Microsoft.Isam.Esent.Interop/Settings.StyleCop @@ -39,11 +39,6 @@ False - - - False - - Microsoft Corporation diff --git a/Src/Microsoft.Isam.Esent.Interop/StringColumnValue.cs b/Src/Microsoft.Isam.Esent.Interop/StringColumnValue.cs index aa5d88a..abc3110 100644 --- a/Src/Microsoft.Isam.Esent.Interop/StringColumnValue.cs +++ b/Src/Microsoft.Isam.Esent.Interop/StringColumnValue.cs @@ -6,6 +6,7 @@ namespace Microsoft.Isam.Esent.Interop { + using System; using System.Diagnostics; /// @@ -13,6 +14,11 @@ namespace Microsoft.Isam.Esent.Interop /// public class StringColumnValue : ColumnValue { + /// + /// Internal value. + /// + private string internalValue; + /// /// Gets the last set or retrieved value of the column. The /// value is returned as a generic object. @@ -27,7 +33,19 @@ namespace Microsoft.Isam.Esent.Interop /// Gets or sets the value of the column. Use to update a /// record with the column value. /// - public string Value { get; set; } + public string Value + { + get + { + return this.internalValue; + } + + set + { + this.internalValue = value; + this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success; + } + } /// /// Gets the byte length of a column value, which is zero if column is null, otherwise diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_err.cs b/Src/Microsoft.Isam.Esent.Interop/jet_err.cs index 686aff6..3dc548e 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_err.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_err.cs @@ -153,6 +153,11 @@ namespace Microsoft.Isam.Esent.Interop /// BadEmptyPage = -351, + /// + /// Number of lines on the page is too few compared to the line being operated on + /// + BadLineCount = -354, + /// /// Key is too large /// @@ -178,6 +183,21 @@ namespace Microsoft.Isam.Esent.Interop /// InvalidPreread = -424, + /// + /// Column reference is invalid + /// + InvalidColumnReference = -426, + + /// + /// Column reference is stale + /// + StaleColumnReference = -427, + + /// + /// A compression integrity check failed. Decompressing data failed the integrity checksum indicating a data corruption in the compress/decompress pipeline. + /// + CompressionIntegrityCheckFailed = -431, + /// /// Logged operation cannot be redone /// @@ -548,6 +568,11 @@ namespace Microsoft.Isam.Esent.Interop /// LogSequenceChecksumMismatch = -590, + /// + /// Database divergence mismatch. Page was uninitialized on remote node, but initialized on local node. + /// + PageInitializedMismatch = -596, + /// /// Unicode translation buffer too small /// @@ -1519,7 +1544,7 @@ namespace Microsoft.Isam.Esent.Interop InvalidLVChunkSize = -1438, /// - /// Only JET_coltypLongText and JET_coltypLongBinary columns can be encrypted + /// Only JET_coltypLongText and JET_coltypLongBinary columns without default values can be encrypted /// ColumnCannotBeEncrypted = -1439, diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs b/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs index ac609c7..9512b5e 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs @@ -43,6 +43,11 @@ namespace Microsoft.Isam.Esent.Interop /// SeparateLongValue = 406, + /// + /// No more records to stream + /// + NoMoreRecords = 428, + /// /// Existing log file has bad signature ///