From 47e6f6aa5f0784823fdba60c1bdd2469c8912c1d Mon Sep 17 00:00:00 2001 From: MichaelGrafnetter Date: Sun, 3 Apr 2016 10:48:33 +0200 Subject: [PATCH] Merge ManagedEsent 1.9.3.3 --- Changelog.txt | 1 + .../ColumnDefinition.cs | 9 +- .../Properties/AssemblyInfo.cs | 11 +- .../config/DatabaseConfig.g.cs | 3 - Src/Microsoft.Isam.Esent.Interop/Api.cs | 62 ++- .../ColumnInfoEnumerator.cs | 5 +- .../EnumeratedColumn.cs | 121 ++++++ .../ErrorExceptions.cs | 108 ++++- .../Esent/AssemblyInfo.cs | 9 +- .../GCHandleCollection.cs | 35 +- Src/Microsoft.Isam.Esent.Interop/IJetApi.cs | 47 ++- Src/Microsoft.Isam.Esent.Interop/JetApi.cs | 270 ++++++++++-- .../MetaDataHelpers.cs | 27 +- .../MoveHelpers.cs | 31 ++ .../NativeMethods.cs | 24 +- .../OnlineMaintenanceHelpers.cs | 44 ++ .../RetrieveColumnHelpers.cs | 18 + Src/Microsoft.Isam.Esent.Interop/Types.cs | 8 +- .../Windows10JetApi.cs | 2 +- .../Windows7Param.cs | 4 +- .../Windows8JetApi.cs | 11 + Src/Microsoft.Isam.Esent.Interop/grbits.cs | 13 +- .../jet_enumcolumn.cs | 4 +- .../jet_enumcolumnvalue.cs | 3 +- Src/Microsoft.Isam.Esent.Interop/jet_err.cs | 17 +- .../jet_indexcreate.cs | 246 +++++------ Src/Microsoft.Isam.Esent.Interop/jet_param.cs | 7 + .../jet_tablecreate.cs | 386 +++++++++--------- .../jet_threadstats.cs | 2 +- .../jet_threadstats2.cs | 2 +- .../jet_unicodeindex2.cs | 3 +- Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs | 5 + 32 files changed, 1132 insertions(+), 406 deletions(-) create mode 100644 Src/Microsoft.Isam.Esent.Interop/EnumeratedColumn.cs create mode 100644 Src/Microsoft.Isam.Esent.Interop/OnlineMaintenanceHelpers.cs diff --git a/Changelog.txt b/Changelog.txt index c14ea52..ca3068c 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,6 +1,7 @@ Version 2.14 - Added support for reading security descriptors (ACLs) from both ntds.dit files and DRS-R. - Added support for the AdminCount attribute. +- Updated the forked ManagedEsent source codes to version 1.9.3.3. Version 2.13.1 - Fixed a bug regarding incorrect OS version detection. diff --git a/Src/Microsoft.Database.Isam/ColumnDefinition.cs b/Src/Microsoft.Database.Isam/ColumnDefinition.cs index f241921..74025f8 100644 --- a/Src/Microsoft.Database.Isam/ColumnDefinition.cs +++ b/Src/Microsoft.Database.Isam/ColumnDefinition.cs @@ -284,12 +284,9 @@ namespace Microsoft.Database.Isam JET_SESID sesid = database.IsamSession.Sesid; - // If we use the wide API (Vista+), then the temp table will be in UTF-16. - // Technically, this should have worked in Vista. But there was a bug, and - // it was fixed after Windows 7. - Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features - ? Encoding.Unicode - : Encoding.ASCII; + // As of Sep 2015, JetGetColumnInfoW is only called for Win8+. Even though Unicode should have + // worked in Win7, it wasn't reliable until Win8. + Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features ? Encoding.Unicode : LibraryHelpers.EncodingASCII; string columnName = Api.RetrieveColumnAsString( database.IsamSession.Sesid, diff --git a/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs b/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs index bf10f1d..b9e806d 100644 --- a/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs +++ b/Src/Microsoft.Database.Isam/Properties/AssemblyInfo.cs @@ -44,11 +44,18 @@ using System.Runtime.InteropServices; // 1.9.2.0 2014.09.11. Isam is placed in the Microsoft.Database namespace. // 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 -[assembly: AssemblyVersion("1.9.3.2")] -[assembly: AssemblyFileVersion("1.9.3.2")] +// 1.9.3.3 2016.03.01. Some bug and perf fixes. +[assembly: AssemblyVersion("1.9.3.3")] +[assembly: AssemblyFileVersion("1.9.3.3")] #if STRONG_NAMED [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("EsentCollectionsTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("EsentInteropTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("InteropApiTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("IsamUnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] #else [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("EsentCollectionsTests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("EsentInteropTests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("InteropApiTests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("IsamUnitTests")] #endif diff --git a/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs b/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs index 8d27f67..18b3db9 100644 --- a/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs +++ b/Src/Microsoft.Database.Isam/config/DatabaseConfig.g.cs @@ -1441,9 +1441,6 @@ namespace Microsoft.Database.Isam.Config /// /// A set of actions to be taken on IOs that appear hung. /// - /// - /// default = (small=nothing, legacy=event on hung IOs) - /// public int HungIOActions { get { return this.GetParam(182); } diff --git a/Src/Microsoft.Isam.Esent.Interop/Api.cs b/Src/Microsoft.Isam.Esent.Interop/Api.cs index 3ac6691..08c1bad 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Api.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Api.cs @@ -49,6 +49,7 @@ namespace Microsoft.Isam.Esent.Interop { using System; + using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Permissions; @@ -1204,6 +1205,8 @@ namespace Microsoft.Isam.Esent.Interop /// The length, in characters, of szKey including the two terminating nulls. /// /// Initial B+ tree density. + /// + /// public static void JetCreateIndex( JET_SESID sesid, JET_TABLEID tableid, @@ -1227,11 +1230,20 @@ namespace Microsoft.Isam.Esent.Interop /// will have exlusive access or the table can be opened for /// exclusive access by passing /// to . + /// + /// and + /// are very similar, and appear to take the same arguments. The difference is in the + /// implementation. JetCreateIndex2 uses LCIDs for Unicode indices (e.g. 1033), while + /// JetCreateIndex4 uses Locale Names (e.g. "en-US" or "de-DE". LCIDs are older, and not as well + /// supported in newer version of windows. + /// /// /// The session to use. /// The table to create the index on. /// Array of objects describing the indexes to be created. /// Number of index description objects. + /// + /// public static void JetCreateIndex2( JET_SESID sesid, JET_TABLEID tableid, @@ -1569,12 +1581,16 @@ namespace Microsoft.Isam.Esent.Interop #endregion /// - /// Ddetermines the name of the current - /// index of a given cursor. This name is also used to later re-select - /// that index as the current index using . - /// It can also be used to discover the properties of that index using - /// JetGetTableIndexInfo. + /// Determines the name of the current index of a given cursor. /// + /// + /// This name is also used to later re-select that index as the current index using + /// . It can also be used to discover the properties of that index using + /// JetGetTableIndexInfo. + /// + /// The returned name of the index will be an empty string if the current index is the clustered index and no + /// primary index was explicitly defined. + /// /// The session to use. /// The cursor to get the index name for. /// Returns the name of the index. @@ -2479,6 +2495,25 @@ namespace Microsoft.Isam.Esent.Interop grbit)); } + /// + /// Efficiently retrieves a set of columns and their values from the + /// current record of a cursor or the copy buffer of that cursor. + /// + /// The session to use. + /// The cursor to retrieve data from. + /// Enumerate options. + /// The discovered columns and their values. + /// A warning or success. + public static JET_wrn JetEnumerateColumns( + JET_SESID sesid, + JET_TABLEID tableid, + EnumerateColumnsGrbit grbit, + out IEnumerable enumeratedColumns) + { + return Api.Check( + Impl.JetEnumerateColumns(sesid, tableid, grbit, out enumeratedColumns)); + } + #endregion #region DML @@ -2776,21 +2811,24 @@ namespace Microsoft.Isam.Esent.Interop /// The session to use for the call. /// The database to be defragmented. /// - /// Unused parameter. Defragmentation is performed for the entire database described by the given database ID. + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. /// /// /// When starting an online defragmentation task, this parameter sets the maximum number of defragmentation /// passes. When stopping an online defragmentation task, this parameter is set to the number of passes - /// performed. + /// performed. This is not honored in all modes (such as ). /// /// /// When starting an online defragmentation task, this parameter sets /// the maximum time for defragmentation. When stopping an online /// defragmentation task, this output buffer is set to the length of - /// time used for defragmentation. + /// time used for defragmentation. This is not honored in all modes (such as ). /// /// Defragmentation options. /// A warning code. + /// public static JET_wrn JetDefragment( JET_SESID sesid, JET_DBID dbid, @@ -2814,18 +2852,20 @@ namespace Microsoft.Isam.Esent.Interop /// The session to use for the call. /// The database to be defragmented. /// - /// Unused parameter. Defragmentation is performed for the entire database described by the given database ID. + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. /// /// /// When starting an online defragmentation task, this parameter sets the maximum number of defragmentation /// passes. When stopping an online defragmentation task, this parameter is set to the number of passes - /// performed. + /// performed. This is not honored in all modes (such as ). /// /// /// When starting an online defragmentation task, this parameter sets /// the maximum time for defragmentation. When stopping an online /// defragmentation task, this output buffer is set to the length of - /// time used for defragmentation. + /// time used for defragmentation. This is not honored in all modes (such as ). /// /// Callback function that defrag uses to report progress. /// Defragmentation options. diff --git a/Src/Microsoft.Isam.Esent.Interop/ColumnInfoEnumerator.cs b/Src/Microsoft.Isam.Esent.Interop/ColumnInfoEnumerator.cs index 6087023..d294b3c 100644 --- a/Src/Microsoft.Isam.Esent.Interop/ColumnInfoEnumerator.cs +++ b/Src/Microsoft.Isam.Esent.Interop/ColumnInfoEnumerator.cs @@ -47,8 +47,9 @@ namespace Microsoft.Isam.Esent.Interop /// A ColumnInfo object containing the information from that record. private static ColumnInfo GetColumnInfoFromColumnlist(JET_SESID sesid, JET_COLUMNLIST columnlist) { - // If we use the wide API (Vista+), then the temp table will be in UTF-16. - Encoding encodingOfTextColumns = EsentVersion.SupportsVistaFeatures ? Encoding.Unicode : LibraryHelpers.EncodingASCII; + // As of Sep 2015, JetGetColumnInfoW is only called for Win8+. Even though Unicode should have + // worked in Win7, it wasn't reliable until Win8. + Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features ? Encoding.Unicode : LibraryHelpers.EncodingASCII; string name = Api.RetrieveColumnAsString( sesid, diff --git a/Src/Microsoft.Isam.Esent.Interop/EnumeratedColumn.cs b/Src/Microsoft.Isam.Esent.Interop/EnumeratedColumn.cs new file mode 100644 index 0000000..ba62783 --- /dev/null +++ b/Src/Microsoft.Isam.Esent.Interop/EnumeratedColumn.cs @@ -0,0 +1,121 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Isam.Esent.Interop +{ + using System; + using System.Globalization; + + /// + /// The values for a given column as generated by Api.EnumerateColumns. + /// + public class EnumeratedColumn + { + /// + /// Gets or sets the column ID of this set of column values. + /// + public JET_COLUMNID Id { get; set; } + + /// + /// Gets or sets the status of this column id. + /// + /// + /// + /// + public JET_err Error { get; set; } + + /// + /// Gets or sets the status of this set of column values. + /// + /// + /// + /// + /// + /// + public JET_wrn Warning { get; set; } + + /// + /// Gets or sets the column values enumerated. + /// + /// + /// This will be null if the column is null or the column values were not provided. + /// + public Value[] Values { get; set; } + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "EnumeratedColumn(0x{0:x}: {1} Values[{2}])", + this.Id, + this.Error != JET_err.Success ? this.Error.ToString() : this.Warning.ToString(), + this.Values.Length); + } + + /// + /// A single column value. + /// + public class Value + { + /// + /// Gets or sets the ordinal of this column value. + /// + /// + /// The lowest valid ordinal is one. + /// This is the same as the "itagSequence" of the column value. + /// + public int Ordinal { get; set; } + + /// + /// Gets or sets the status of this column value. + /// + /// + /// + /// + /// + /// + /// + /// + public JET_wrn Warning { get; set; } + + /// + /// Gets or sets the column value as bytes. + /// + /// + /// This will be null if the column is null or the column values were not provided. + /// This will be truncated if Warning is . + /// + public byte[] Bytes { get; set; } + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + const int MaxLength = 16; + return string.Format( + CultureInfo.InvariantCulture, + "EnumeratedColumn.Value({0}: {1} Bytes[{2}] = {3}{4}{5}{6})", + this.Ordinal, + this.Warning, + this.Bytes.Length, + '{', + BitConverter.ToString(this.Bytes, 0, Math.Min(this.Bytes.Length, MaxLength)), + this.Bytes.Length > MaxLength ? "..." : string.Empty, + '}'); + } + } + } +} \ No newline at end of file diff --git a/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs b/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs index f25fae7..c970035 100644 --- a/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs +++ b/Src/Microsoft.Isam.Esent.Interop/ErrorExceptions.cs @@ -3334,7 +3334,7 @@ namespace Microsoft.Isam.Esent.Interop "SA1402:FileMayOnlyContainASingleClass", Justification = "Auto-generated code.")] [Serializable] - public sealed class EsentDbTimeTooOldException : EsentInconsistentException + public sealed class EsentDbTimeTooOldException : EsentCorruptionException { /// /// Initializes a new instance of the EsentDbTimeTooOldException class. @@ -3366,7 +3366,7 @@ namespace Microsoft.Isam.Esent.Interop "SA1402:FileMayOnlyContainASingleClass", Justification = "Auto-generated code.")] [Serializable] - public sealed class EsentDbTimeTooNewException : EsentInconsistentException + public sealed class EsentDbTimeTooNewException : EsentCorruptionException { /// /// Initializes a new instance of the EsentDbTimeTooNewException class. @@ -3838,6 +3838,38 @@ namespace Microsoft.Isam.Esent.Interop #endif } + /// + /// Base class for JET_err.LogSequenceChecksumMismatch exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentLogSequenceChecksumMismatchException : EsentCorruptionException + { + /// + /// Initializes a new instance of the EsentLogSequenceChecksumMismatchException class. + /// + public EsentLogSequenceChecksumMismatchException() : + base("The previous log's accumulated segment checksum doesn't match the next log", JET_err.LogSequenceChecksumMismatch) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentLogSequenceChecksumMismatchException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentLogSequenceChecksumMismatchException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + /// /// Base class for JET_err.UnicodeTranslationBufferTooSmall exceptions. /// @@ -9708,7 +9740,7 @@ namespace Microsoft.Isam.Esent.Interop /// Initializes a new instance of the EsentSecondaryIndexCorruptedException class. /// public EsentSecondaryIndexCorruptedException() : - base("Secondary index is corrupt. The database must be defragmented or the affected index must be deleted. If the corrupt index is over Unicode text, a likely cause a sort-order change.", JET_err.SecondaryIndexCorrupted) + base("Secondary index is corrupt. The database must be defragmented or the affected index must be deleted. If the corrupt index is over Unicode text, a likely cause is a sort-order change.", JET_err.SecondaryIndexCorrupted) { } @@ -11358,6 +11390,38 @@ namespace Microsoft.Isam.Esent.Interop #endif } + /// + /// Base class for JET_err.EncryptionBadItag exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentEncryptionBadItagException : EsentUsageException + { + /// + /// Initializes a new instance of the EsentEncryptionBadItagException class. + /// + public EsentEncryptionBadItagException() : + base("Cannot encrypt tagged columns with itag>1", JET_err.EncryptionBadItag) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentEncryptionBadItagException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentEncryptionBadItagException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + /// /// Base class for JET_err.TooManySorts exceptions. /// @@ -11614,6 +11678,38 @@ namespace Microsoft.Isam.Esent.Interop #endif } + /// + /// Base class for JET_err.FileAlreadyExists exceptions. + /// + [SuppressMessage( + "Microsoft.StyleCop.CSharp.MaintainabilityRules", + "SA1402:FileMayOnlyContainASingleClass", + Justification = "Auto-generated code.")] + [Serializable] + public sealed class EsentFileAlreadyExistsException : EsentInconsistentException + { + /// + /// Initializes a new instance of the EsentFileAlreadyExistsException class. + /// + public EsentFileAlreadyExistsException() : + base("File already exists", JET_err.FileAlreadyExists) + { + } + +#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR. + /// + /// Initializes a new instance of the EsentFileAlreadyExistsException class. This constructor + /// is used to deserialize a serialized exception. + /// + /// The data needed to deserialize the object. + /// The deserialization context. + private EsentFileAlreadyExistsException(SerializationInfo info, StreamingContext context) : + base(info, context) + { + } +#endif + } + /// /// Base class for JET_err.AfterInitialization exceptions. /// @@ -12986,6 +13082,8 @@ namespace Microsoft.Isam.Esent.Interop return new EsentRecoveredWithoutUndoDatabasesConsistentException(); case JET_err.CommittedLogFileCorrupt: return new EsentCommittedLogFileCorruptException(); + case JET_err.LogSequenceChecksumMismatch: + return new EsentLogSequenceChecksumMismatchException(); case JET_err.UnicodeTranslationBufferTooSmall: return new EsentUnicodeTranslationBufferTooSmallException(); case JET_err.UnicodeTranslationFail: @@ -13456,6 +13554,8 @@ namespace Microsoft.Isam.Esent.Interop return new EsentUpdateMustVersionException(); case JET_err.DecryptionFailed: return new EsentDecryptionFailedException(); + case JET_err.EncryptionBadItag: + return new EsentEncryptionBadItagException(); case JET_err.TooManySorts: return new EsentTooManySortsException(); case JET_err.InvalidOnSort: @@ -13472,6 +13572,8 @@ namespace Microsoft.Isam.Esent.Interop return new EsentFileNotFoundException(); case JET_err.FileInvalidType: return new EsentFileInvalidTypeException(); + case JET_err.FileAlreadyExists: + return new EsentFileAlreadyExistsException(); case JET_err.AfterInitialization: return new EsentAfterInitializationException(); case JET_err.LogCorrupted: diff --git a/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs b/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs index 2db6e4d..09d0ec9 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Esent/AssemblyInfo.cs @@ -52,13 +52,15 @@ using System.Runtime.InteropServices; // 1.9.2.0 2014.09.11. Isam is placed in the Microsoft.Database namespace. // 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 -[assembly: AssemblyVersion("1.9.3.2")] -[assembly: AssemblyFileVersion("1.9.3.2")] +// 1.9.3.3 2016.03.01. Some bug and perf fixes. +[assembly: AssemblyVersion("1.9.3.3")] +[assembly: AssemblyFileVersion("1.9.3.3")] #if STRONG_NAMED -[assembly: InternalsVisibleTo("InteropApiTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] [assembly: InternalsVisibleTo("EsentInteropWsaTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] [assembly: InternalsVisibleTo("Esent.Isam, PublicKey=002400000480000094000000060200000024000052534131000400000100010077154b93d8084f0f30c52174d6c93d25ffdc65e11ba1b125383e55c6095061df3c2f765401c21434aa413aa264b6eb3039d95c5f33a9d4eb7deb695b55e434d8dd9b42e0e86f3287498732d3a30d0ee22d8d58b2361f033351d5c1a64a16324ac6c42b5a4b14c12483b52a98a43f7e934df86b92cc8a9c4ee0f408d7b6d987e3")] +[assembly: InternalsVisibleTo("InteropApiTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] +[assembly: InternalsVisibleTo("IsamUnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] [assembly: InternalsVisibleTo("Pixie, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] [assembly: InternalsVisibleTo("PixieTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")] @@ -66,6 +68,7 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] #else [assembly: InternalsVisibleTo("InteropApiTests")] +[assembly: InternalsVisibleTo("IsamUnitTests")] [assembly: InternalsVisibleTo("EsentInteropTestsImmersive")] [assembly: InternalsVisibleTo("EsentInteropWsaTests")] [assembly: InternalsVisibleTo("Esent.Isam")] diff --git a/Src/Microsoft.Isam.Esent.Interop/GCHandleCollection.cs b/Src/Microsoft.Isam.Esent.Interop/GCHandleCollection.cs index 14a775f..6282834 100644 --- a/Src/Microsoft.Isam.Esent.Interop/GCHandleCollection.cs +++ b/Src/Microsoft.Isam.Esent.Interop/GCHandleCollection.cs @@ -21,7 +21,12 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// /// The handles of the objects being pinned. /// - private List handles; + private GCHandle[] handles; + + /// + /// Handle count + /// + private int count; /// /// Disposes of the object. @@ -30,9 +35,9 @@ namespace Microsoft.Isam.Esent.Interop.Implementation { if (null != this.handles) { - foreach (GCHandle handle in this.handles) - { - handle.Free(); + for (int i = 0; i < this.count; i++) + { + this.handles[i].Free(); } this.handles = null; @@ -57,15 +62,33 @@ namespace Microsoft.Isam.Esent.Interop.Implementation if (null == this.handles) { - this.handles = new List(); + this.handles = new GCHandle[4]; // same as List + } + else if (this.count == this.handles.Length) + { + Array.Resize(ref this.handles, this.count * 2); } + Debug.Assert(this.count < this.handles.Length, "Index out of bound"); + GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned); - this.handles.Add(handle); + this.handles[this.count++] = handle; IntPtr pinned = handle.AddrOfPinnedObject(); Debug.Assert(IntPtr.Zero != pinned, "Pinned object has null address"); return pinned; } + + /// + /// Set handle array capacity. + /// + /// Estimated handle count + public void SetCapacity(int capacity) + { + if (null == this.handles) + { + this.handles = new GCHandle[capacity]; + } + } } } diff --git a/Src/Microsoft.Isam.Esent.Interop/IJetApi.cs b/Src/Microsoft.Isam.Esent.Interop/IJetApi.cs index 8398822..ee253ba 100644 --- a/Src/Microsoft.Isam.Esent.Interop/IJetApi.cs +++ b/Src/Microsoft.Isam.Esent.Interop/IJetApi.cs @@ -7,6 +7,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation { using System; + using System.Collections.Generic; using Microsoft.Isam.Esent.Interop.Server2003; using Microsoft.Isam.Esent.Interop.Vista; using Microsoft.Isam.Esent.Interop.Windows7; @@ -2154,6 +2155,21 @@ namespace Microsoft.Isam.Esent.Interop.Implementation int maxDataSize, EnumerateColumnsGrbit grbit); + /// + /// Efficiently retrieves a set of columns and their values from the + /// current record of a cursor or the copy buffer of that cursor. + /// + /// The session to use. + /// The cursor to retrieve data from. + /// Enumerate options. + /// The discovered columns and their values. + /// A warning or success. + int JetEnumerateColumns( + JET_SESID sesid, + JET_TABLEID tableid, + EnumerateColumnsGrbit grbit, + out IEnumerable enumeratedColumns); + #if !MANAGEDESENT_ON_WSA // Not exposed in MSDK /// /// Retrieves record size information from the desired location. @@ -2375,21 +2391,24 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// The session to use for the call. /// The database to be defragmented. /// - /// Unused parameter. Defragmentation is performed for the entire database described by the given database ID. + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. /// /// /// When starting an online defragmentation task, this parameter sets the maximum number of defragmentation /// passes. When stopping an online defragmentation task, this parameter is set to the number of passes - /// performed. + /// performed. This is not honored in all modes (such as ). /// /// /// When starting an online defragmentation task, this parameter sets /// the maximum time for defragmentation. When stopping an online /// defragmentation task, this output buffer is set to the length of - /// time used for defragmentation. + /// time used for defragmentation. This is not honored in all modes (such as ). /// /// Defragmentation options. /// An error code or warning. + /// . int JetDefragment( JET_SESID sesid, JET_DBID dbid, @@ -2398,6 +2417,26 @@ namespace Microsoft.Isam.Esent.Interop.Implementation ref int seconds, DefragGrbit grbit); + /// + /// Starts and stops database defragmentation tasks that improves data + /// organization within a database. + /// + /// The session to use for the call. + /// The database to be defragmented. + /// + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. + /// + /// Defragmentation options. + /// An error code or warning. + /// . + int Defragment( + JET_SESID sesid, + JET_DBID dbid, + string tableName, + DefragGrbit grbit); + /// /// Starts and stops database defragmentation tasks that improves data /// organization within a database. @@ -2465,4 +2504,4 @@ namespace Microsoft.Isam.Esent.Interop.Implementation #endregion } -} \ No newline at end of file +} diff --git a/Src/Microsoft.Isam.Esent.Interop/JetApi.cs b/Src/Microsoft.Isam.Esent.Interop/JetApi.cs index eb497bf..a65a7db 100644 --- a/Src/Microsoft.Isam.Esent.Interop/JetApi.cs +++ b/Src/Microsoft.Isam.Esent.Interop/JetApi.cs @@ -13,6 +13,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; + using System.Threading; using Microsoft.Isam.Esent.Interop.Server2003; using Microsoft.Isam.Esent.Interop.Vista; using Microsoft.Isam.Esent.Interop.Windows7; @@ -1850,7 +1851,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation { fixed (JET_THREADSTATS* rawJetThreadstats = &threadstats) { - return Err(NativeMethods.JetGetThreadStats(rawJetThreadstats, JET_THREADSTATS.Size)); + return Err(NativeMethods.JetGetThreadStats(rawJetThreadstats, checked((uint)JET_THREADSTATS.Size))); } } } @@ -2825,7 +2826,9 @@ namespace Microsoft.Isam.Esent.Interop.Implementation var nativeColumnlist = new NATIVE_COLUMNLIST(); nativeColumnlist.cbStruct = checked((uint)Marshal.SizeOf(typeof(NATIVE_COLUMNLIST))); - if (this.Capabilities.SupportsVistaFeatures) + // Technically, this should have worked in Vista. But there was a bug, and + // it was fixed after Windows 7. + if (this.Capabilities.SupportsWindows8Features) { err = Err(NativeMethods.JetGetTableColumnInfoW( sesid.Value, @@ -4453,6 +4456,8 @@ namespace Microsoft.Isam.Esent.Interop.Implementation uint* rgcbKeys = stackalloc uint[keyCount]; using (var gchandlecollection = new GCHandleCollection()) { + gchandlecollection.SetCapacity(keyCount); + for (int i = 0; i < keyCount; ++i) { rgpvKeys[i] = (void*)gchandlecollection.Add(keys[keyIndex + i]); @@ -4764,6 +4769,132 @@ namespace Microsoft.Isam.Esent.Interop.Implementation } } + /// + /// Efficiently retrieves a set of columns and their values from the + /// current record of a cursor or the copy buffer of that cursor. + /// + /// The session to use. + /// The cursor to retrieve data from. + /// Enumerate options. + /// The discovered columns and their values. + /// A warning or success. + public int JetEnumerateColumns( + JET_SESID sesid, + JET_TABLEID tableid, + EnumerateColumnsGrbit grbit, + out IEnumerable enumeratedColumns) + { + unsafe + { + // NOTE: We must never throw an exception up through ESE or it will corrupt its internal state! + Exception allocatorException = null; + JET_PFNREALLOC allocator = (c, pv, cb) => + { + try + { + if (pv == IntPtr.Zero) + { + // NOTE: this will allocate memory if cb == 0 and that is what we want. + return Marshal.AllocHGlobal(new IntPtr(cb)); + } + + if (cb == 0) + { + Marshal.FreeHGlobal(pv); + return IntPtr.Zero; + } + + return Marshal.ReAllocHGlobal(pv, new IntPtr(cb)); + } + catch (OutOfMemoryException) + { + return IntPtr.Zero; + } +#if !MANAGEDESENT_ON_WSA // Thread model has changed in windows store apps. + catch (ThreadAbortException e) + { + LibraryHelpers.ThreadResetAbort(); + allocatorException = e; + return IntPtr.Zero; + } +#endif + catch (Exception e) + { + allocatorException = e; + return IntPtr.Zero; + } + }; + + uint nativeEnumColumnCount; + NATIVE_ENUMCOLUMN* nativeEnumColumns; + int err = Implementation.NativeMethods.JetEnumerateColumns( + sesid.Value, + tableid.Value, + 0, + null, + out nativeEnumColumnCount, + out nativeEnumColumns, + allocator, + IntPtr.Zero, + int.MaxValue, + (uint)(grbit & ~EnumerateColumnsGrbit.EnumerateCompressOutput)); + + var columns = new EnumeratedColumn[nativeEnumColumnCount]; + for (int i = 0; i < nativeEnumColumnCount; ++i) + { + columns[i] = new EnumeratedColumn(); + columns[i].Id = new JET_COLUMNID { Value = nativeEnumColumns[i].columnid }; + columns[i].Error = nativeEnumColumns[i].err < 0 ? (JET_err)nativeEnumColumns[i].err : JET_err.Success; + columns[i].Warning = nativeEnumColumns[i].err > 0 ? (JET_wrn)nativeEnumColumns[i].err : JET_wrn.Success; + if ((JET_wrn)nativeEnumColumns[i].err == JET_wrn.Success) + { + EnumeratedColumn.Value[] values = new EnumeratedColumn.Value[nativeEnumColumns[i].cEnumColumnValue]; + columns[i].Values = values; + for (int j = 0; j < nativeEnumColumns[i].cEnumColumnValue; j++) + { + values[j] = new EnumeratedColumn.Value(); + values[j].Ordinal = j + 1; + values[j].Warning = (JET_wrn)nativeEnumColumns[i].rgEnumColumnValue[j].err; + values[j].Bytes = new byte[(int)nativeEnumColumns[i].rgEnumColumnValue[j].cbData]; + Marshal.Copy( + nativeEnumColumns[i].rgEnumColumnValue[j].pvData, + values[j].Bytes, + 0, + (int)nativeEnumColumns[i].rgEnumColumnValue[j].cbData); + if (nativeEnumColumns[i].rgEnumColumnValue[j].pvData != IntPtr.Zero) + { + allocator(IntPtr.Zero, nativeEnumColumns[i].rgEnumColumnValue[j].pvData, 0); + } + } + + if (nativeEnumColumns[i].rgEnumColumnValue != null) + { + allocator(IntPtr.Zero, new IntPtr(nativeEnumColumns[i].rgEnumColumnValue), 0); + } + } + } + + if (nativeEnumColumns != null) + { + allocator(IntPtr.Zero, new IntPtr(nativeEnumColumns), 0); + } + + if (allocatorException != null) + { +#if !MANAGEDESENT_ON_WSA // Thread model has changed in Windows store apps. + if (allocatorException is ThreadAbortException) + { + Thread.CurrentThread.Abort(); + } +#endif + throw allocatorException; + } + + enumeratedColumns = columns; + return Err(err); + } + } + #if !MANAGEDESENT_ON_WSA // Not exposed in MSDK /// /// Retrieves record size information from the desired location. @@ -5113,21 +5244,25 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// The session to use for the call. /// The database to be defragmented. /// - /// Unused parameter. Defragmentation is performed for the entire database described by the given database ID. + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. /// /// /// When starting an online defragmentation task, this parameter sets the maximum number of defragmentation /// passes. When stopping an online defragmentation task, this parameter is set to the number of passes - /// performed. + /// performed. This is not honored in all modes (such as ). /// /// /// When starting an online defragmentation task, this parameter sets /// the maximum time for defragmentation. When stopping an online /// defragmentation task, this output buffer is set to the length of - /// time used for defragmentation. + /// time used for defragmentation. This is not honored in all modes (such as ). /// /// Defragmentation options. /// An error code. + /// . + /// . public int JetDefragment(JET_SESID sesid, JET_DBID dbid, string tableName, ref int passes, ref int seconds, DefragGrbit grbit) { #if MANAGEDESENT_ON_WSA @@ -5151,22 +5286,55 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// The session to use for the call. /// The database to be defragmented. /// - /// Unused parameter. Defragmentation is performed for the entire database described by the given database ID. + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. + /// + /// Defragmentation options. + /// An error code. + /// . + public int Defragment( + JET_SESID sesid, + JET_DBID dbid, + string tableName, + DefragGrbit grbit) + { +#if MANAGEDESENT_ON_WSA + return this.Defragment2(sesid, dbid, tableName, null, grbit); +#else + TraceFunctionCall("Defragment"); + int err = Err(NativeMethods.JetDefragment( + sesid.Value, dbid.Value, tableName, IntPtr.Zero, IntPtr.Zero, (uint)grbit)); + return err; +#endif + } + + /// + /// Starts and stops database defragmentation tasks that improves data + /// organization within a database. + /// + /// The session to use for the call. + /// The database to be defragmented. + /// + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. /// /// /// When starting an online defragmentation task, this parameter sets the maximum number of defragmentation /// passes. When stopping an online defragmentation task, this parameter is set to the number of passes - /// performed. + /// performed. This is not honored in all modes (such as ). /// /// /// When starting an online defragmentation task, this parameter sets /// the maximum time for defragmentation. When stopping an online /// defragmentation task, this output buffer is set to the length of - /// time used for defragmentation. + /// time used for defragmentation. This is not honored in all modes (such as ). /// /// Callback function that defrag uses to report progress. /// Defragmentation options. /// An error code or warning. + /// . public int JetDefragment2( JET_SESID sesid, JET_DBID dbid, @@ -5207,6 +5375,58 @@ namespace Microsoft.Isam.Esent.Interop.Implementation return err; } + //// Currently, this overload of JetDefragment2() is not used outside of WSA. +#if MANAGEDESENT_ON_WSA + /// + /// Starts and stops database defragmentation tasks that improves data + /// organization within a database. + /// + /// The session to use for the call. + /// The database to be defragmented. + /// + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. + /// + /// Callback function that defrag uses to report progress. + /// Defragmentation options. + /// An error code or warning. + /// . + public int Defragment2( + JET_SESID sesid, + JET_DBID dbid, + string tableName, + JET_CALLBACK callback, + DefragGrbit grbit) + { + TraceFunctionCall("Defragment2"); + + IntPtr functionPointer; + if (null == callback) + { + functionPointer = IntPtr.Zero; + } + else + { + JetCallbackWrapper callbackWrapper = this.callbackWrappers.Add(callback); + functionPointer = Marshal.GetFunctionPointerForDelegate(callbackWrapper.NativeCallback); +#if DEBUG + GC.Collect(); +#endif + } + +#if MANAGEDESENT_ON_WSA + int err = Err(NativeMethods.JetDefragment2W( + sesid.Value, dbid.Value, tableName, IntPtr.Zero, IntPtr.Zero, functionPointer, (uint)grbit)); +#else + int err = Err(NativeMethods.JetDefragment2( + sesid.Value, dbid.Value, tableName, IntPtr.Zero, IntPtr.Zero, functionPointer, (uint)grbit)); +#endif + this.callbackWrappers.Collect(); + return err; + } +#endif + #if !MANAGEDESENT_ON_WSA // Not exposed in MSDK /// /// Performs idle cleanup tasks or checks the version store status in ESE. @@ -5625,15 +5845,15 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// Index create structures to convert. /// The handle collection used to pin the data. /// Pinned native versions of the index creates. - private static unsafe NATIVE_INDEXCREATE[] GetNativeIndexCreates( + private static unsafe JET_INDEXCREATE.NATIVE_INDEXCREATE[] GetNativeIndexCreates( IList managedIndexCreates, ref GCHandleCollection handles) { - NATIVE_INDEXCREATE[] nativeIndices = null; + JET_INDEXCREATE.NATIVE_INDEXCREATE[] nativeIndices = null; if (managedIndexCreates != null && managedIndexCreates.Count > 0) { - nativeIndices = new NATIVE_INDEXCREATE[managedIndexCreates.Count]; + nativeIndices = new JET_INDEXCREATE.NATIVE_INDEXCREATE[managedIndexCreates.Count]; for (int i = 0; i < managedIndexCreates.Count; ++i) { @@ -5662,15 +5882,15 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// Index create structures to convert. /// The handle collection used to pin the data. /// Pinned native versions of the index creates. - private static unsafe NATIVE_INDEXCREATE1[] GetNativeIndexCreate1s( + private static unsafe JET_INDEXCREATE.NATIVE_INDEXCREATE1[] GetNativeIndexCreate1s( IList managedIndexCreates, ref GCHandleCollection handles) { - NATIVE_INDEXCREATE1[] nativeIndices = null; + JET_INDEXCREATE.NATIVE_INDEXCREATE1[] nativeIndices = null; if (managedIndexCreates != null && managedIndexCreates.Count > 0) { - nativeIndices = new NATIVE_INDEXCREATE1[managedIndexCreates.Count]; + nativeIndices = new JET_INDEXCREATE.NATIVE_INDEXCREATE1[managedIndexCreates.Count]; for (int i = 0; i < managedIndexCreates.Count; ++i) { @@ -5700,15 +5920,15 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// Index create structures to convert. /// The handle collection used to pin the data. /// Pinned native versions of the index creates. - private static unsafe NATIVE_INDEXCREATE2[] GetNativeIndexCreate2s( + private static unsafe JET_INDEXCREATE.NATIVE_INDEXCREATE2[] GetNativeIndexCreate2s( IList managedIndexCreates, ref GCHandleCollection handles) { - NATIVE_INDEXCREATE2[] nativeIndices = null; + JET_INDEXCREATE.NATIVE_INDEXCREATE2[] nativeIndices = null; if (managedIndexCreates != null && managedIndexCreates.Count > 0) { - nativeIndices = new NATIVE_INDEXCREATE2[managedIndexCreates.Count]; + nativeIndices = new JET_INDEXCREATE.NATIVE_INDEXCREATE2[managedIndexCreates.Count]; for (int i = 0; i < managedIndexCreates.Count; ++i) { @@ -5772,7 +5992,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation var handles = new GCHandleCollection(); try { - NATIVE_INDEXCREATE[] nativeIndexcreates = GetNativeIndexCreates(indexcreates, ref handles); + JET_INDEXCREATE.NATIVE_INDEXCREATE[] nativeIndexcreates = GetNativeIndexCreates(indexcreates, ref handles); return Err(NativeMethods.JetCreateIndex2(sesid.Value, tableid.Value, nativeIndexcreates, checked((uint)numIndexCreates))); } finally @@ -5795,7 +6015,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation var handles = new GCHandleCollection(); try { - NATIVE_INDEXCREATE1[] nativeIndexcreates = GetNativeIndexCreate1s(indexcreates, ref handles); + JET_INDEXCREATE.NATIVE_INDEXCREATE1[] nativeIndexcreates = GetNativeIndexCreate1s(indexcreates, ref handles); return Err(NativeMethods.JetCreateIndex2W(sesid.Value, tableid.Value, nativeIndexcreates, checked((uint)numIndexCreates))); } finally @@ -5818,7 +6038,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation var handles = new GCHandleCollection(); try { - NATIVE_INDEXCREATE2[] nativeIndexcreates = GetNativeIndexCreate2s(indexcreates, ref handles); + JET_INDEXCREATE.NATIVE_INDEXCREATE2[] nativeIndexcreates = GetNativeIndexCreate2s(indexcreates, ref handles); return Err(NativeMethods.JetCreateIndex3W(sesid.Value, tableid.Value, nativeIndexcreates, checked((uint)numIndexCreates))); } finally @@ -5839,7 +6059,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation JET_DBID dbid, JET_TABLECREATE tablecreate) { - NATIVE_TABLECREATE3 nativeTableCreate = tablecreate.GetNativeTableCreate3(); + JET_TABLECREATE.NATIVE_TABLECREATE3 nativeTableCreate = tablecreate.GetNativeTableCreate3(); unsafe { @@ -5850,7 +6070,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation nativeTableCreate.rgcolumncreate = (NATIVE_COLUMNCREATE*)GetNativeColumnCreates(tablecreate.rgcolumncreate, true, ref handles); // Convert/pin the index definitions. - NATIVE_INDEXCREATE2[] nativeIndexCreates = GetNativeIndexCreate2s(tablecreate.rgindexcreate, ref handles); + JET_INDEXCREATE.NATIVE_INDEXCREATE2[] nativeIndexCreates = GetNativeIndexCreate2s(tablecreate.rgindexcreate, ref handles); nativeTableCreate.rgindexcreate = handles.Add(nativeIndexCreates); // Convert/pin the space hints. @@ -6089,15 +6309,15 @@ namespace Microsoft.Isam.Esent.Interop.Implementation JET_DBID dbid, JET_TABLECREATE tablecreate) { - NATIVE_TABLECREATE2 nativeTableCreate = tablecreate.GetNativeTableCreate2(); + JET_TABLECREATE.NATIVE_TABLECREATE2 nativeTableCreate = tablecreate.GetNativeTableCreate2(); unsafe { var handles = new GCHandleCollection(); try { - NATIVE_INDEXCREATE1[] nativeIndexCreate1s = null; - NATIVE_INDEXCREATE[] nativeIndexCreates = null; + JET_INDEXCREATE.NATIVE_INDEXCREATE1[] nativeIndexCreate1s = null; + JET_INDEXCREATE.NATIVE_INDEXCREATE[] nativeIndexCreates = null; int err; if (this.Capabilities.SupportsVistaFeatures) diff --git a/Src/Microsoft.Isam.Esent.Interop/MetaDataHelpers.cs b/Src/Microsoft.Isam.Esent.Interop/MetaDataHelpers.cs index 350bede..b2fc423 100644 --- a/Src/Microsoft.Isam.Esent.Interop/MetaDataHelpers.cs +++ b/Src/Microsoft.Isam.Esent.Interop/MetaDataHelpers.cs @@ -119,8 +119,9 @@ namespace Microsoft.Isam.Esent.Interop JET_COLUMNLIST columnlist; JetGetTableColumnInfo(sesid, tableid, string.Empty, out columnlist); - // If we use the wide API (Vista+), then the temp table will be in UTF-16. - Encoding encodingOfTextColumns = EsentVersion.SupportsVistaFeatures ? Encoding.Unicode : LibraryHelpers.EncodingASCII; + // As of Sep 2015, JetGetColumnInfoW is only called for Win8+. Even though Unicode should have + // worked in Win7, it wasn't reliable until Win8. + Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features ? Encoding.Unicode : LibraryHelpers.EncodingASCII; try { @@ -267,5 +268,27 @@ namespace Microsoft.Isam.Esent.Interop return true; } + + /// + /// Determines the name of the current index of a given cursor. + /// + /// + /// This name is also used to later re-select that index as the current index using + /// . It can also be used to discover the properties of that index using + /// JetGetTableIndexInfo. + /// + /// The returned name of the index will be null if the current index is the clustered index and no primary + /// index was explicitly defined. + /// + /// The session to use. + /// The cursor to get the index name for. + /// Returns the name of the index. + public static string JetGetCurrentIndex(JET_SESID sesid, JET_TABLEID tableid) + { + string indexName; + Api.JetGetCurrentIndex(sesid, tableid, out indexName, SystemParameters.NameMost); + + return string.IsNullOrEmpty(indexName) ? null : indexName; + } } } diff --git a/Src/Microsoft.Isam.Esent.Interop/MoveHelpers.cs b/Src/Microsoft.Isam.Esent.Interop/MoveHelpers.cs index 9d9c651..0d9d712 100644 --- a/Src/Microsoft.Isam.Esent.Interop/MoveHelpers.cs +++ b/Src/Microsoft.Isam.Esent.Interop/MoveHelpers.cs @@ -209,5 +209,36 @@ namespace Microsoft.Isam.Esent.Interop return new GenericEnumerable(() => new IntersectIndexesEnumerator(sesid, ranges)); } + + /// + /// Positions a cursor to an index entry for the record that is associated with + /// the specified bookmark. The bookmark can be used with any index defined over + /// a table. The bookmark for a record can be retrieved using . + /// + /// The session to use. + /// The cursor to position. + /// The bookmark used to position the cursor. + /// The size of the bookmark. + /// True if a record matching the bookmark was found. + public static bool TryGotoBookmark(JET_SESID sesid, JET_TABLEID tableid, byte[] bookmark, int bookmarkSize) + { + var err = (JET_err)Impl.JetGotoBookmark(sesid, tableid, bookmark, bookmarkSize); + + // Return false if the record no longer exists. + if (JET_err.RecordDeleted == err) + { + return false; + } + + // Return false if there is no entry for this record on the current (secondary) index. + if (JET_err.NoCurrentRecord == err) + { + return false; + } + + Api.Check((int)err); + Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error"); + return true; + } } } diff --git a/Src/Microsoft.Isam.Esent.Interop/NativeMethods.cs b/Src/Microsoft.Isam.Esent.Interop/NativeMethods.cs index 8422705..b1bf102 100644 --- a/Src/Microsoft.Isam.Esent.Interop/NativeMethods.cs +++ b/Src/Microsoft.Isam.Esent.Interop/NativeMethods.cs @@ -527,18 +527,18 @@ namespace Microsoft.Isam.Esent.Interop.Implementation [DllImport(EsentDll, CharSet = EsentCharSet, ExactSpelling = true)] public static extern int JetCreateIndex2( - IntPtr sesid, IntPtr tableid, [In] NATIVE_INDEXCREATE[] pindexcreate, uint cIndexCreate); + IntPtr sesid, IntPtr tableid, [In] JET_INDEXCREATE.NATIVE_INDEXCREATE[] pindexcreate, uint cIndexCreate); // Introduced in Windows Vista, this version takes the larger NATIVE_INDEXCREATE1 structure. [DllImport(EsentDll, CharSet = CharSet.Unicode, ExactSpelling = true)] public static extern int JetCreateIndex2W( - IntPtr sesid, IntPtr tableid, [In] NATIVE_INDEXCREATE1[] pindexcreate, uint cIndexCreate); + IntPtr sesid, IntPtr tableid, [In] JET_INDEXCREATE.NATIVE_INDEXCREATE1[] pindexcreate, uint cIndexCreate); // Introduced in Windows 7, this version takes the larger NATIVE_INDEXCREATE2 structure, supporting // space hints. [DllImport(EsentDll, CharSet = CharSet.Unicode, ExactSpelling = true)] public static extern int JetCreateIndex3W( - IntPtr sesid, IntPtr tableid, [In] NATIVE_INDEXCREATE2[] pindexcreate, uint cIndexCreate); + IntPtr sesid, IntPtr tableid, [In] JET_INDEXCREATE.NATIVE_INDEXCREATE2[] pindexcreate, uint cIndexCreate); [DllImport(EsentDll, ExactSpelling = true)] public static extern int JetOpenTempTable( @@ -589,15 +589,15 @@ namespace Microsoft.Isam.Esent.Interop.Implementation #if !MANAGEDESENT_ON_WSA // Not exposed in MSDK [DllImport(EsentDll, CharSet = EsentCharSet, ExactSpelling = true)] - public static extern int JetCreateTableColumnIndex2(IntPtr sesid, uint dbid, ref NATIVE_TABLECREATE2 tablecreate3); + public static extern int JetCreateTableColumnIndex2(IntPtr sesid, uint dbid, ref JET_TABLECREATE.NATIVE_TABLECREATE2 tablecreate3); // Introduced in Vista. [DllImport(EsentDll, CharSet = CharSet.Unicode, ExactSpelling = true)] - public static extern int JetCreateTableColumnIndex2W(IntPtr sesid, uint dbid, ref NATIVE_TABLECREATE2 tablecreate3); + public static extern int JetCreateTableColumnIndex2W(IntPtr sesid, uint dbid, ref JET_TABLECREATE.NATIVE_TABLECREATE2 tablecreate3); // Introduced in Windows 7 [DllImport(EsentDll, CharSet = CharSet.Unicode, ExactSpelling = true)] - public static extern int JetCreateTableColumnIndex3W(IntPtr sesid, uint dbid, ref NATIVE_TABLECREATE3 tablecreate3); + public static extern int JetCreateTableColumnIndex3W(IntPtr sesid, uint dbid, ref JET_TABLECREATE.NATIVE_TABLECREATE3 tablecreate3); #endif // !MANAGEDESENT_ON_WSA #region JetGetTableColumnInfo overlaods. @@ -1197,15 +1197,27 @@ namespace Microsoft.Isam.Esent.Interop.Implementation public static extern int JetDefragment( IntPtr sesid, uint dbid, string szTableName, ref uint pcPasses, ref uint pcSeconds, uint grbit); + [DllImport(EsentDll, CharSet = EsentCharSet, ExactSpelling = true)] + public static extern int JetDefragment( + IntPtr sesid, uint dbid, string szTableName, IntPtr pcPasses, IntPtr pcSeconds, uint grbit); + [DllImport(EsentDll, CharSet = EsentCharSet, ExactSpelling = true)] public static extern int JetDefragment2( IntPtr sesid, uint dbid, string szTableName, ref uint pcPasses, ref uint pcSeconds, IntPtr callback, uint grbit); + + [DllImport(EsentDll, CharSet = EsentCharSet, ExactSpelling = true)] + public static extern int JetDefragment2( + IntPtr sesid, uint dbid, string szTableName, IntPtr pcPasses, IntPtr pcSeconds, IntPtr callback, uint grbit); #endif // !MANAGEDESENT_ON_WSA [DllImport(EsentDll, CharSet = CharSet.Unicode, ExactSpelling = true)] public static extern int JetDefragment2W( IntPtr sesid, uint dbid, string szTableName, ref uint pcPasses, ref uint pcSeconds, IntPtr callback, uint grbit); + [DllImport(EsentDll, CharSet = CharSet.Unicode, ExactSpelling = true)] + public static extern int JetDefragment2W( + IntPtr sesid, uint dbid, string szTableName, IntPtr pcPasses, IntPtr pcSeconds, IntPtr callback, uint grbit); + #if !MANAGEDESENT_ON_WSA // Not exposed in MSDK [DllImport(EsentDll, ExactSpelling = true)] public static extern int JetIdle(IntPtr sesid, uint grbit); diff --git a/Src/Microsoft.Isam.Esent.Interop/OnlineMaintenanceHelpers.cs b/Src/Microsoft.Isam.Esent.Interop/OnlineMaintenanceHelpers.cs new file mode 100644 index 0000000..f94cc3c --- /dev/null +++ b/Src/Microsoft.Isam.Esent.Interop/OnlineMaintenanceHelpers.cs @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Isam.Esent.Interop +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Text; + using Microsoft.Isam.Esent.Interop.Implementation; + + /// + /// Helper methods for the ESENT API. These methods deal with database + /// meta-data. + /// + public static partial class Api + { + /// + /// Starts and stops database defragmentation tasks that improves data + /// organization within a database. + /// + /// The session to use for the call. + /// The database to be defragmented. + /// + /// Under some options defragmentation is performed for the entire database described by the given + /// database ID, and other options (such as ) require + /// the name of the table to defragment. + /// + /// Defragmentation options. + /// A warning code. + /// + public static JET_wrn Defragment( + JET_SESID sesid, + JET_DBID dbid, + string tableName, + DefragGrbit grbit) + { + return Api.Check(Impl.Defragment(sesid, dbid, tableName, grbit)); + } + } +} diff --git a/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs b/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs index e8bdc0c..b074aa1 100644 --- a/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs +++ b/Src/Microsoft.Isam.Esent.Interop/RetrieveColumnHelpers.cs @@ -896,6 +896,24 @@ namespace Microsoft.Isam.Esent.Interop ColumnValue.RetrieveColumns(sesid, tableid, values); } + /// + /// Efficiently retrieves a set of columns and their values from the + /// current record of a cursor or the copy buffer of that cursor. + /// + /// The session to use. + /// The cursor to retrieve data from. + /// Enumerate options. + /// The discovered columns and their values. + public static IEnumerable EnumerateColumns( + JET_SESID sesid, + JET_TABLEID tableid, + EnumerateColumnsGrbit grbit) + { + IEnumerable enumeratedColumns; + Api.JetEnumerateColumns(sesid, tableid, grbit, out enumeratedColumns); + return enumeratedColumns; + } + /// /// Create the nullable return value. /// diff --git a/Src/Microsoft.Isam.Esent.Interop/Types.cs b/Src/Microsoft.Isam.Esent.Interop/Types.cs index cb9fdd1..6a0fdb7 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Types.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Types.cs @@ -530,7 +530,7 @@ namespace Microsoft.Isam.Esent.Interop /// True if lhs comes before rhs. public static bool operator <(JET_COLUMNID lhs, JET_COLUMNID rhs) { - return lhs.CompareTo(rhs) < 0; + return lhs.Value < rhs.Value; } /// @@ -541,7 +541,7 @@ namespace Microsoft.Isam.Esent.Interop /// True if lhs comes after rhs. public static bool operator >(JET_COLUMNID lhs, JET_COLUMNID rhs) { - return lhs.CompareTo(rhs) > 0; + return lhs.Value > rhs.Value; } /// @@ -553,7 +553,7 @@ namespace Microsoft.Isam.Esent.Interop /// True if lhs comes before or is equal to rhs. public static bool operator <=(JET_COLUMNID lhs, JET_COLUMNID rhs) { - return lhs.CompareTo(rhs) <= 0; + return lhs.Value <= rhs.Value; } /// @@ -565,7 +565,7 @@ namespace Microsoft.Isam.Esent.Interop /// True if lhs comes after or is equal to rhs. public static bool operator >=(JET_COLUMNID lhs, JET_COLUMNID rhs) { - return lhs.CompareTo(rhs) >= 0; + return lhs.Value >= rhs.Value; } /// diff --git a/Src/Microsoft.Isam.Esent.Interop/Windows10JetApi.cs b/Src/Microsoft.Isam.Esent.Interop/Windows10JetApi.cs index f5ee3fc..6cd5a87 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Windows10JetApi.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Windows10JetApi.cs @@ -117,7 +117,7 @@ namespace Microsoft.Isam.Esent.Interop.Implementation { fixed (JET_THREADSTATS2* rawJetThreadstats = &threadstats) { - return Err(NativeMethods.JetGetThreadStats(rawJetThreadstats, JET_THREADSTATS2.Size)); + return Err(NativeMethods.JetGetThreadStats(rawJetThreadstats, checked((uint)JET_THREADSTATS2.Size))); } } } diff --git a/Src/Microsoft.Isam.Esent.Interop/Windows7Param.cs b/Src/Microsoft.Isam.Esent.Interop/Windows7Param.cs index 6203396..2126c84 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Windows7Param.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Windows7Param.cs @@ -19,7 +19,9 @@ namespace Microsoft.Isam.Esent.Interop.Windows7 public const JET_param WaypointLatency = (JET_param)153; /// - /// Turn on/off automatic sequential B-tree defragmentation. + /// Turn on/off automatic sequential B-tree defragmentation tasks (On by + /// default, but also requires flags / .RetrieveHintTableScan* + /// to trigger on any given tables). /// public const JET_param DefragmentSequentialBTrees = (JET_param)160; diff --git a/Src/Microsoft.Isam.Esent.Interop/Windows8JetApi.cs b/Src/Microsoft.Isam.Esent.Interop/Windows8JetApi.cs index c6d465b..4ac0477 100644 --- a/Src/Microsoft.Isam.Esent.Interop/Windows8JetApi.cs +++ b/Src/Microsoft.Isam.Esent.Interop/Windows8JetApi.cs @@ -129,7 +129,18 @@ namespace Microsoft.Isam.Esent.Interop.Implementation /// The table to create the index on. /// Array of objects describing the indexes to be created. /// Number of index description objects. + /// + /// + /// and + /// are very similar, and appear to take the same arguments. The difference is in the + /// implementation. JetCreateIndex2 uses LCIDs for Unicode indices (e.g. 1033), while + /// JetCreateIndex4 uses Locale Names (e.g. "en-US" or "de-DE". LCIDs are older, and not as well + /// supported in newer version of windows. + /// + /// /// An error code. + /// + /// public int JetCreateIndex4( JET_SESID sesid, JET_TABLEID tableid, diff --git a/Src/Microsoft.Isam.Esent.Interop/grbits.cs b/Src/Microsoft.Isam.Esent.Interop/grbits.cs index b6effbb..773ff76 100644 --- a/Src/Microsoft.Isam.Esent.Interop/grbits.cs +++ b/Src/Microsoft.Isam.Esent.Interop/grbits.cs @@ -7,6 +7,7 @@ namespace Microsoft.Isam.Esent.Interop { using System; + using System.Collections.Generic; /// /// Options for . @@ -744,7 +745,8 @@ namespace Microsoft.Isam.Esent.Interop } /// - /// Options for . + /// Options for + /// and its associated overloads. /// /// /// @@ -792,7 +794,8 @@ namespace Microsoft.Isam.Esent.Interop /// the default value. No effort is made to remove column values that /// match their default values. /// It is important to remember that this option affects the output of - /// when used with + /// + /// and its associated overloads when used with /// or /// . /// @@ -1742,13 +1745,15 @@ namespace Microsoft.Isam.Esent.Interop /// /// By setting this the client indicates that forward sequential scan is - /// the predominant usage pattern of this table. + /// the predominant usage pattern of this table (causing B+ Tree defrag to + /// be auto-triggered to clean it up if fragmented). /// RetrieveHintTableScanForward = 0x00000010, /// /// By setting this the client indicates that backwards sequential scan - /// is the predominant usage pattern of this table. + /// is the predominant usage pattern of this table(causing B+ Tree defrag to + /// be auto-triggered to clean it up if fragmented). /// RetrieveHintTableScanBackward = 0x00000020, diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumn.cs b/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumn.cs index 9af5d68..74f854b 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumn.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumn.cs @@ -155,8 +155,8 @@ namespace Microsoft.Isam.Esent.Interop /// . /// This points to memory allocated with the /// allocator callback passed to - /// . Remember to - /// release the memory when finished. + /// . + /// Remember to release the memory when finished. /// public IntPtr pvData { get; internal set; } diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumnvalue.cs b/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumnvalue.cs index 04b36a2..a30dd16 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumnvalue.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_enumcolumnvalue.cs @@ -47,7 +47,8 @@ namespace Microsoft.Isam.Esent.Interop /// /// Enumerates the column values of a record using the JetEnumerateColumns - /// function. returns an array of JET_ENUMCOLUMNVALUE + /// function. + /// returns an array of JET_ENUMCOLUMNVALUE /// structures. The array is returned in memory that was allocated using /// the callback that was supplied to that function. /// diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_err.cs b/Src/Microsoft.Isam.Esent.Interop/jet_err.cs index b03c2d8..686aff6 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_err.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_err.cs @@ -543,6 +543,11 @@ namespace Microsoft.Isam.Esent.Interop /// CommittedLogFileCorrupt = -586, + /// + /// The previous log's accumulated segment checksum doesn't match the next log + /// + LogSequenceChecksumMismatch = -590, + /// /// Unicode translation buffer too small /// @@ -1459,7 +1464,7 @@ namespace Microsoft.Isam.Esent.Interop PrimaryIndexCorrupted = -1413, /// - /// Secondary index is corrupt. The database must be defragmented or the affected index must be deleted. If the corrupt index is over Unicode text, a likely cause a sort-order change. + /// Secondary index is corrupt. The database must be defragmented or the affected index must be deleted. If the corrupt index is over Unicode text, a likely cause is a sort-order change. /// SecondaryIndexCorrupted = -1414, @@ -1718,6 +1723,11 @@ namespace Microsoft.Isam.Esent.Interop /// DecryptionFailed = -1622, + /// + /// Cannot encrypt tagged columns with itag>1 + /// + EncryptionBadItag = -1623, + /// /// Too many sort processes /// @@ -1758,6 +1768,11 @@ namespace Microsoft.Isam.Esent.Interop /// FileInvalidType = -1812, + /// + /// File already exists + /// + FileAlreadyExists = -1814, + /// /// Cannot Restore after init. /// diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_indexcreate.cs b/Src/Microsoft.Isam.Esent.Interop/jet_indexcreate.cs index f794f26..8a2ea6e 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_indexcreate.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_indexcreate.cs @@ -13,129 +13,6 @@ namespace Microsoft.Isam.Esent.Interop using System.Runtime.InteropServices; using Microsoft.Isam.Esent.Interop.Vista; -#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK - /// - /// The native version of the JET_INDEXCREATE structure. - /// - [StructLayout(LayoutKind.Sequential)] - [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", - "SA1305:FieldNamesMustNotUseHungarianNotation", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - [SuppressMessage( - "Microsoft.StyleCop.CSharp.NamingRules", - "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - internal unsafe struct NATIVE_INDEXCREATE - { - /// - /// Size of the structure. - /// - public uint cbStruct; - - /// - /// Name of the index. - /// - public IntPtr szIndexName; - - /// - /// Index key description. - /// - public IntPtr szKey; - - /// - /// Size of index key description. - /// - public uint cbKey; - - /// - /// Index options. - /// - public uint grbit; - - /// - /// Index density. - /// - public uint ulDensity; - - /// - /// Pointer to unicode sort options. - /// - public NATIVE_UNICODEINDEX* pidxUnicode; - - /// - /// Maximum size of column data to index. This can also be - /// a pointer to a JET_TUPLELIMITS structure. - /// - public IntPtr cbVarSegMac; - - /// - /// Pointer to array of conditional columns. - /// - public IntPtr rgconditionalcolumn; - - /// - /// Count of conditional columns. - /// - public uint cConditionalColumn; - - /// - /// Returned error from index creation. - /// - public int err; - } - - /// - /// The native version of the JET_INDEXCREATE structure. This version includes the cbKeyMost - /// member, which is only valid on Windows Vista and above, but the name of the structure - /// was not changed for Vista. - /// - [StructLayout(LayoutKind.Sequential)] - [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", - "SA1305:FieldNamesMustNotUseHungarianNotation", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - [SuppressMessage( - "Microsoft.StyleCop.CSharp.NamingRules", - "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - internal struct NATIVE_INDEXCREATE1 - { - /// - /// Nested NATIVE_INDEXCREATE structure. - /// - public NATIVE_INDEXCREATE indexcreate; - - /// - /// Maximum size of the key. - /// - public uint cbKeyMost; - } - - /// - /// The native version of the JET_INDEXCREATE2 structure. Introduced in Windows 7, - /// this includes a member. - /// - [StructLayout(LayoutKind.Sequential)] - [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", - "SA1305:FieldNamesMustNotUseHungarianNotation", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - [SuppressMessage( - "Microsoft.StyleCop.CSharp.NamingRules", - "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - internal struct NATIVE_INDEXCREATE2 - { - /// - /// Nested NATIVE_INDEXCREATE1 structure. - /// - public NATIVE_INDEXCREATE1 indexcreate1; - - /// - /// A pointer. - /// - public IntPtr pSpaceHints; - } -#endif // !MANAGEDESENT_ON_WSA - /// /// Contains the information needed to create an index over data in an ESE database. /// @@ -579,5 +456,128 @@ namespace Microsoft.Isam.Esent.Interop return true; } + +#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK + /// + /// The native version of the JET_INDEXCREATE structure. + /// + [StructLayout(LayoutKind.Sequential)] + [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", + "SA1305:FieldNamesMustNotUseHungarianNotation", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + [SuppressMessage( + "Microsoft.StyleCop.CSharp.NamingRules", + "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + internal unsafe struct NATIVE_INDEXCREATE + { + /// + /// Size of the structure. + /// + public uint cbStruct; + + /// + /// Name of the index. + /// + public IntPtr szIndexName; + + /// + /// Index key description. + /// + public IntPtr szKey; + + /// + /// Size of index key description. + /// + public uint cbKey; + + /// + /// Index options. + /// + public uint grbit; + + /// + /// Index density. + /// + public uint ulDensity; + + /// + /// Pointer to unicode sort options. + /// + public NATIVE_UNICODEINDEX* pidxUnicode; + + /// + /// Maximum size of column data to index. This can also be + /// a pointer to a JET_TUPLELIMITS structure. + /// + public IntPtr cbVarSegMac; + + /// + /// Pointer to array of conditional columns. + /// + public IntPtr rgconditionalcolumn; + + /// + /// Count of conditional columns. + /// + public uint cConditionalColumn; + + /// + /// Returned error from index creation. + /// + public int err; + } + + /// + /// The native version of the JET_INDEXCREATE2 structure. Introduced in Windows 7, + /// this includes a member. + /// + [StructLayout(LayoutKind.Sequential)] + [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", + "SA1305:FieldNamesMustNotUseHungarianNotation", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + [SuppressMessage( + "Microsoft.StyleCop.CSharp.NamingRules", + "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + internal struct NATIVE_INDEXCREATE2 + { + /// + /// Nested NATIVE_INDEXCREATE1 structure. + /// + public NATIVE_INDEXCREATE1 indexcreate1; + + /// + /// A pointer. + /// + public IntPtr pSpaceHints; + } + + /// + /// The native version of the JET_INDEXCREATE structure. This version includes the cbKeyMost + /// member, which is only valid on Windows Vista and above, but the name of the structure + /// was not changed for Vista. + /// + [StructLayout(LayoutKind.Sequential)] + [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", + "SA1305:FieldNamesMustNotUseHungarianNotation", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + [SuppressMessage( + "Microsoft.StyleCop.CSharp.NamingRules", + "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + internal struct NATIVE_INDEXCREATE1 + { + /// + /// Nested NATIVE_INDEXCREATE structure. + /// + public NATIVE_INDEXCREATE indexcreate; + + /// + /// Maximum size of the key. + /// + public uint cbKeyMost; + } +#endif // !MANAGEDESENT_ON_WSA } } diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_param.cs b/Src/Microsoft.Isam.Esent.Interop/jet_param.cs index a203ee9..464bcaa 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_param.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_param.cs @@ -421,6 +421,13 @@ namespace Microsoft.Isam.Esent.Interop /// VersionStoreTaskQueueMax = 105, + /// + /// This parameter controls whether perfmon counters should be enabled or not. + /// By default, perfmon counters are enabled, but there is memory overhead for enabling + /// them. + /// + DisablePerfmon = 107, + // If you can not find the parameter you are expecting here, then perhaps it is // in a later version of the API, in VistaParam, Windows7Param, etc. } diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_tablecreate.cs b/Src/Microsoft.Isam.Esent.Interop/jet_tablecreate.cs index af869a4..ea38c69 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_tablecreate.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_tablecreate.cs @@ -13,199 +13,6 @@ namespace Microsoft.Isam.Esent.Interop using System.Runtime.InteropServices; using Microsoft.Isam.Esent.Interop.Implementation; -#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK - /// - /// The native version of the structure. This includes callbacks, - /// space hints, and uses NATIVE_INDEXCREATE. - /// - [StructLayout(LayoutKind.Sequential)] - [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", - "SA1305:FieldNamesMustNotUseHungarianNotation", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - [SuppressMessage( - "Microsoft.StyleCop.CSharp.NamingRules", - "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - internal unsafe struct NATIVE_TABLECREATE2 - { - /// - /// Size of the structure. - /// - public uint cbStruct; - - /// - /// Name of the table to create. - /// - [MarshalAs(UnmanagedType.LPTStr)] - public string szTableName; - - /// - /// Name of the table from which to inherit base DDL. - /// - [MarshalAs(UnmanagedType.LPTStr)] - public string szTemplateTableName; - - /// - /// Initial pages to allocate for table. - /// - public uint ulPages; - - /// - /// Table density. - /// - public uint ulDensity; - - /// - /// Array of column creation info. - /// - public NATIVE_COLUMNCREATE* rgcolumncreate; - - /// - /// Number of columns to create. - /// - public uint cColumns; - - /// - /// Array of indices to create, pointer to . - /// - public IntPtr rgindexcreate; - - /// - /// Number of indices to create. - /// - public uint cIndexes; - - /// - /// Callback function to use for the table. - /// - [MarshalAs(UnmanagedType.LPTStr)] - public string szCallback; - - /// - /// Type of the callback function. - /// - public JET_cbtyp cbtyp; - - /// - /// Table options. - /// - public uint grbit; - - /// - /// Returned tabledid. - /// - public IntPtr tableid; - - /// - /// Count of objects created (columns+table+indexes+callbacks). - /// - public uint cCreated; - } - - /// - /// The native version of the structure. This includes callbacks, - /// space hints, and uses NATIvE_INDEXCREATE2. - /// - [StructLayout(LayoutKind.Sequential)] - [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", - "SA1305:FieldNamesMustNotUseHungarianNotation", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - [SuppressMessage( - "Microsoft.StyleCop.CSharp.NamingRules", - "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", - Justification = "This should match the unmanaged API, which isn't capitalized.")] - internal unsafe struct NATIVE_TABLECREATE3 - { - /// - /// Size of the structure. - /// - public uint cbStruct; - - /// - /// Name of the table to create. - /// - [MarshalAs(UnmanagedType.LPWStr)] - public string szTableName; - - /// - /// Name of the table from which to inherit base DDL. - /// - [MarshalAs(UnmanagedType.LPWStr)] - public string szTemplateTableName; - - /// - /// Initial pages to allocate for table. - /// - public uint ulPages; - - /// - /// Table density. - /// - public uint ulDensity; - - /// - /// Array of column creation info. - /// - public NATIVE_COLUMNCREATE* rgcolumncreate; - - /// - /// Number of columns to create. - /// - public uint cColumns; - - /// - /// Array of indices to create, pointer to . - /// - public IntPtr rgindexcreate; - - /// - /// Number of indices to create. - /// - public uint cIndexes; - - /// - /// Callback function to use for the table. - /// - [MarshalAs(UnmanagedType.LPWStr)] - public string szCallback; - - /// - /// Type of the callback function. - /// - public JET_cbtyp cbtyp; - - /// - /// Table options. - /// - public uint grbit; - - /// - /// Space allocation, maintenance, and usage hints for default sequential index. - /// - public NATIVE_SPACEHINTS* pSeqSpacehints; - - /// - /// Space allocation, maintenance, and usage hints for Separated LV tree. - /// - public NATIVE_SPACEHINTS* pLVSpacehints; - - /// - /// Heuristic size to separate a intrinsic LV from the primary record. - /// - public uint cbSeparateLV; - - /// - /// Returned tabledid. - /// - public IntPtr tableid; - - /// - /// Count of objects created (columns+table+indexes+callbacks). - /// - public uint cCreated; - } -#endif // !MANAGEDESENT_ON_WSA - /// /// Contains the information needed to create a table in an ESE database. /// @@ -643,5 +450,198 @@ namespace Microsoft.Isam.Esent.Interop /// Whether the additional fields in /// are the same as this. partial void NotYetPublishedEquals(JET_TABLECREATE other, ref bool notYetPublishedEquals); + +#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK + /// + /// The native version of the structure. This includes callbacks, + /// space hints, and uses NATIVE_INDEXCREATE. + /// + [StructLayout(LayoutKind.Sequential)] + [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", + "SA1305:FieldNamesMustNotUseHungarianNotation", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + [SuppressMessage( + "Microsoft.StyleCop.CSharp.NamingRules", + "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + internal unsafe struct NATIVE_TABLECREATE2 + { + /// + /// Size of the structure. + /// + public uint cbStruct; + + /// + /// Name of the table to create. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string szTableName; + + /// + /// Name of the table from which to inherit base DDL. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string szTemplateTableName; + + /// + /// Initial pages to allocate for table. + /// + public uint ulPages; + + /// + /// Table density. + /// + public uint ulDensity; + + /// + /// Array of column creation info. + /// + public NATIVE_COLUMNCREATE* rgcolumncreate; + + /// + /// Number of columns to create. + /// + public uint cColumns; + + /// + /// Array of indices to create, pointer to . + /// + public IntPtr rgindexcreate; + + /// + /// Number of indices to create. + /// + public uint cIndexes; + + /// + /// Callback function to use for the table. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string szCallback; + + /// + /// Type of the callback function. + /// + public JET_cbtyp cbtyp; + + /// + /// Table options. + /// + public uint grbit; + + /// + /// Returned tabledid. + /// + public IntPtr tableid; + + /// + /// Count of objects created (columns+table+indexes+callbacks). + /// + public uint cCreated; + } + + /// + /// The native version of the structure. This includes callbacks, + /// space hints, and uses NATIvE_INDEXCREATE2. + /// + [StructLayout(LayoutKind.Sequential)] + [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", + "SA1305:FieldNamesMustNotUseHungarianNotation", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + [SuppressMessage( + "Microsoft.StyleCop.CSharp.NamingRules", + "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", + Justification = "This should match the unmanaged API, which isn't capitalized.")] + internal unsafe struct NATIVE_TABLECREATE3 + { + /// + /// Size of the structure. + /// + public uint cbStruct; + + /// + /// Name of the table to create. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string szTableName; + + /// + /// Name of the table from which to inherit base DDL. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string szTemplateTableName; + + /// + /// Initial pages to allocate for table. + /// + public uint ulPages; + + /// + /// Table density. + /// + public uint ulDensity; + + /// + /// Array of column creation info. + /// + public NATIVE_COLUMNCREATE* rgcolumncreate; + + /// + /// Number of columns to create. + /// + public uint cColumns; + + /// + /// Array of indices to create, pointer to . + /// + public IntPtr rgindexcreate; + + /// + /// Number of indices to create. + /// + public uint cIndexes; + + /// + /// Callback function to use for the table. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string szCallback; + + /// + /// Type of the callback function. + /// + public JET_cbtyp cbtyp; + + /// + /// Table options. + /// + public uint grbit; + + /// + /// Space allocation, maintenance, and usage hints for default sequential index. + /// + public NATIVE_SPACEHINTS* pSeqSpacehints; + + /// + /// Space allocation, maintenance, and usage hints for Separated LV tree. + /// + public NATIVE_SPACEHINTS* pLVSpacehints; + + /// + /// Heuristic size to separate a intrinsic LV from the primary record. + /// + public uint cbSeparateLV; + + /// + /// Returned tabledid. + /// + public IntPtr tableid; + + /// + /// Count of objects created (columns+table+indexes+callbacks). + /// + public uint cCreated; + } +#endif // !MANAGEDESENT_ON_WSA } } diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_threadstats.cs b/Src/Microsoft.Isam.Esent.Interop/jet_threadstats.cs index 433cdb9..65bbbbd 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_threadstats.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_threadstats.cs @@ -31,7 +31,7 @@ namespace Microsoft.Isam.Esent.Interop.Vista /// /// The size of a JET_THREADSTATS structure. /// - internal static readonly uint Size = checked((uint)Marshal.SizeOf(typeof(JET_THREADSTATS))); + internal static readonly int Size = Marshal.SizeOf(typeof(JET_THREADSTATS)); /// /// Size of the structure. This is used for interop. diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_threadstats2.cs b/Src/Microsoft.Isam.Esent.Interop/jet_threadstats2.cs index 36ce29d..77231ba 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_threadstats2.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_threadstats2.cs @@ -31,7 +31,7 @@ namespace Microsoft.Isam.Esent.Interop.Windows10 /// /// The size of a JET_THREADSTATS2 structure. /// - internal static readonly uint Size = checked((uint)Marshal.SizeOf(typeof(JET_THREADSTATS2))); + internal static readonly int Size = Marshal.SizeOf(typeof(JET_THREADSTATS2)); /// /// Size of the structure. This is used for interop. diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_unicodeindex2.cs b/Src/Microsoft.Isam.Esent.Interop/jet_unicodeindex2.cs index 50e9be8..37a5cc0 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_unicodeindex2.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_unicodeindex2.cs @@ -51,6 +51,7 @@ namespace Microsoft.Isam.Esent.Interop static JET_UNICODEINDEX() { // Some common LCIDs are listed at http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx. + LcidToLocales.Add(127, string.Empty); LcidToLocales.Add(1033, "en-us"); LcidToLocales.Add(1046, "pt-br"); LcidToLocales.Add(3084, "fr-ca"); @@ -63,7 +64,7 @@ namespace Microsoft.Isam.Esent.Interop /// A BCP-47 style locale name. public string GetEffectiveLocaleName() { - if (!string.IsNullOrEmpty(this.szLocaleName)) + if (this.szLocaleName != null) { return this.szLocaleName; } diff --git a/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs b/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs index 2822fd7..ac609c7 100644 --- a/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs +++ b/Src/Microsoft.Isam.Esent.Interop/jet_wrn.cs @@ -223,6 +223,11 @@ namespace Microsoft.Isam.Esent.Interop /// ColumnNotInRecord = 1539, + /// + /// Column value returned as a reference because it could not be reconstructed from the data in the record + /// + ColumnReference = 1541, + /// /// Data has changed ///