Check() static private method

Throw an exception if the parameter is an ESE error, returns a JET_wrn otherwise.
static private Check ( int err ) : JET_wrn
err int The error code to check.
return JET_wrn
 /// <summary>
 /// Starts and stops database defragmentation tasks that improves data
 /// organization within a database.
 /// </summary>
 /// <param name="sesid">The session to use for the call.</param>
 /// <param name="dbid">The database to be defragmented.</param>
 /// <param name="tableName">
 /// Under some options defragmentation is performed for the entire database described by the given
 /// database ID, and other options (such as <see cref="Windows7.Windows7Grbits.DefragmentBTree"/>) require
 /// the name of the table to defragment.
 /// </param>
 /// <param name="grbit">Defragmentation options.</param>
 /// <returns>A warning code.</returns>
 /// <seealso cref="Api.JetDefragment"/>
 public static JET_wrn Defragment(
     JET_SESID sesid,
     JET_DBID dbid,
     string tableName,
     DefragGrbit grbit)
 {
     return(Api.Check(Impl.Defragment(sesid, dbid, tableName, grbit)));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Removes an index range created with <see cref="JetSetIndexRange"/> or
        /// <see cref="TrySetIndexRange"/>. If no index range is present this
        /// method does nothing.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor to remove the index range on.</param>
        public static void ResetIndexRange(JET_SESID sesid, JET_TABLEID tableid)
        {
            var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, SetIndexRangeGrbit.RangeRemove);

            if (err >= JET_err.Success || JET_err.InvalidOperation == err)
            {
                return;
            }

            Api.Check((int)err);
            throw new NotImplementedException("Unreachable code");
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Temporarily limits the set of index entries that the cursor can walk using
        /// JetMove to those starting from the current index entry and ending at the index
        /// entry that matches the search criteria specified by the search key in that cursor
        /// and the specified bound criteria. A search key must have been previously constructed
        /// using JetMakeKey. Returns true if the index range is non-empty, false otherwise.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor to position.</param>
        /// <param name="grbit">Seek option.</param>
        /// <returns>True if the seek was successful.</returns>
        public static bool TrySetIndexRange(JET_SESID sesid, JET_TABLEID tableid, SetIndexRangeGrbit grbit)
        {
            var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, grbit);

            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);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Removes an index range created with <see cref="JetSetIndexRange"/> or
        /// <see cref="TrySetIndexRange"/>. If no index range is present this
        /// method does nothing.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor to remove the index range on.</param>
        public static void ResetIndexRange(JET_SESID sesid, JET_TABLEID tableid)
        {
            var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, SetIndexRangeGrbit.RangeRemove);

            if (JET_err.InvalidOperation == err)
            {
                // this error is expected if there isn't currently an index range
                return;
            }

            Api.Check((int)err);
            return;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Try to move to the next record in the table. If there is not a next record
        /// this returns false, if a different error is encountered an exception is thrown.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor to position.</param>
        /// <returns>True if the move was successful.</returns>
        public static bool TryMoveNext(JET_SESID sesid, JET_TABLEID tableid)
        {
            var err = (JET_err)Impl.JetMove(sesid, tableid, (int)JET_Move.Next, MoveGrbit.None);

            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);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Explicitly reserve the ability to update a row, write lock, or to explicitly prevent a row from
        /// being updated by any other session, read lock. Normally, row write locks are acquired implicitly as a
        /// result of updating rows. Read locks are usually not required because of record versioning. However,
        /// in some cases a transaction may desire to explicitly lock a row to enforce serialization, or to ensure
        /// that a subsequent operation will succeed.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor to use. A lock will be acquired on the current record.</param>
        /// <param name="grbit">Lock options, use this to specify which type of lock to obtain.</param>
        /// <returns>
        /// True if the lock was obtained, false otherwise. An exception is thrown if an unexpected
        /// error is encountered.
        /// </returns>
        public static bool TryGetLock(JET_SESID sesid, JET_TABLEID tableid, GetLockGrbit grbit)
        {
            var err = (JET_err)Impl.JetGetLock(sesid, tableid, grbit);

            if (JET_err.WriteConflict == err)
            {
                return(false);
            }

            Api.Check((int)err);
            Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
            return(true);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Retrieves columns into ColumnValue objects.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor retrieve the data from. The cursor should be positioned on a record.</param>
        /// <param name="values">The values to retrieve.</param>
        public static void RetrieveColumns(JET_SESID sesid, JET_TABLEID tableid, params ColumnValue[] values)
        {
            if (null == values)
            {
                throw new ArgumentNullException("values");
            }

            if (0 == values.Length)
            {
                throw new ArgumentOutOfRangeException("values", values.Length, "must have at least one value");
            }

            Api.Check(ColumnValue.RetrieveColumns(sesid, tableid, values));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Retrieve the value for columns whose buffers were truncated.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The table to use.</param>
        /// <param name="columnValues">The column values.</param>
        /// <param name="nativeRetrievecolumns">
        /// The native retrieve columns that match the column values.
        /// </param>
        private static unsafe void RetrieveTruncatedBuffers(JET_SESID sesid, JET_TABLEID tableid, IList <ColumnValue> columnValues, NATIVE_RETRIEVECOLUMN *nativeRetrievecolumns)
        {
            for (int i = 0; i < columnValues.Count; ++i)
            {
                if (nativeRetrievecolumns[i].err == (int)JET_wrn.BufferTruncated)
                {
                    var buffer = new byte[nativeRetrievecolumns[i].cbActual];
                    int actualSize;
                    int err;
                    var retinfo = new JET_RETINFO {
                        itagSequence = columnValues[i].ItagSequence
                    };

                    // Pin the buffer and retrieve the data
                    fixed(byte *pinnedBuffer = buffer)
                    {
                        err = Api.Impl.JetRetrieveColumn(
                            sesid,
                            tableid,
                            columnValues[i].Columnid,
                            new IntPtr(pinnedBuffer),
                            buffer.Length,
                            out actualSize,
                            columnValues[i].RetrieveGrbit,
                            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;

                    // For BytesColumnValue this will copy the data to a new array.
                    // If this situation becomes common we should simply use the array.
                    columnValues[i].GetValueFromBytes(buffer, 0, actualSize, err);
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Retrieves information about indexes on a table.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The table to retrieve index information about.</param>
        /// <param name="indexname">The name of the index.</param>
        /// <param name="result">Filled in with information about indexes on the table.</param>
        /// <param name="infoLevel">The type of information to retrieve.</param>
        /// <returns>true if there was no error, false if the index wasn't found. Throws for other Jet errors.</returns>
        public static bool TryJetGetTableIndexInfo(
            JET_SESID sesid,
            JET_TABLEID tableid,
            string indexname,
            out JET_INDEXID result,
            JET_IdxInfo infoLevel)
        {
            int err = Impl.JetGetTableIndexInfo(sesid, tableid, indexname, out result, infoLevel);

            if ((JET_err)err == JET_err.IndexNotFound)
            {
                return(false);
            }

            Api.Check(err);

            return(true);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Try to open a table.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="dbid">The database to look for the table in.</param>
        /// <param name="tablename">The name of the table.</param>
        /// <param name="grbit">Table open options.</param>
        /// <param name="tableid">Returns the opened tableid.</param>
        /// <returns>True if the table was opened, false if the table doesn't exist.</returns>
        public static bool TryOpenTable(
            JET_SESID sesid,
            JET_DBID dbid,
            string tablename,
            OpenTableGrbit grbit,
            out JET_TABLEID tableid)
        {
            var err = (JET_err)Impl.JetOpenTable(sesid, dbid, tablename, null, 0, grbit, out tableid);

            if (JET_err.ObjectNotFound == err)
            {
                return(false);
            }

            Api.Check((int)err);
            Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
            return(true);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Sets columns from ColumnValue objects.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor to update. An update should be prepared.</param>
        /// <param name="values">The values to set.</param>
        public static void SetColumns(JET_SESID sesid, JET_TABLEID tableid, params ColumnValue[] values)
        {
            if (null == values)
            {
                throw new ArgumentNullException("values");
            }

            if (0 == values.Length)
            {
                throw new ArgumentOutOfRangeException("values", values.Length, "must have at least one value");
            }

            unsafe
            {
                NATIVE_SETCOLUMN *nativeSetcolumns = stackalloc NATIVE_SETCOLUMN[values.Length];
                Api.Check(values[0].SetColumns(sesid, tableid, values, nativeSetcolumns, 0));
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// 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 <see cref="JetGetBookmark"/>.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The cursor to position.</param>
        /// <param name="bookmark">The bookmark used to position the cursor.</param>
        /// <param name="bookmarkSize">The size of the bookmark.</param>
        /// <returns>True if a record matching the bookmark was found.</returns>
        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);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Retrieve the value for columns whose buffers were truncated.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">The table to use.</param>
        /// <param name="columnValues">The column values.</param>
        /// <param name="nativeRetrievecolumns">
        /// The native retrieve columns that match the column values.
        /// </param>
        private static unsafe void RetrieveTruncatedBuffers(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_RETRIEVECOLUMN *nativeRetrievecolumns)
        {
            for (int i = 0; i < columnValues.Length; ++i)
            {
                if (nativeRetrievecolumns[i].err == (int)JET_wrn.BufferTruncated)
                {
                    var buffer = new byte[nativeRetrievecolumns[i].cbActual];
                    int actualSize;
                    int err;
                    var retinfo = new JET_RETINFO {
                        itagSequence = columnValues[i].ItagSequence
                    };

                    // Pin the buffer and retrieve the data
                    fixed(byte *pinnedBuffer = buffer)
                    {
                        err = Api.Impl.JetRetrieveColumn(
                            sesid,
                            tableid,
                            columnValues[i].Columnid,
                            new IntPtr(pinnedBuffer),
                            buffer.Length,
                            out actualSize,
                            columnValues[i].RetrieveGrbit,
                            retinfo);
                    }

                    // Set the error in the ColumnValue before checkin it
                    columnValues[i].Error = (JET_err)err;
                    Api.Check(err);

                    // For BytesColumnValue this will copy the data to a new array.
                    // If this situation becomes common we should simply use the array.
                    columnValues[i].GetValueFromBytes(buffer, 0, actualSize, err);
                }
            }
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Constructs search keys that may then be used by JetSeek and JetSetIndexRange.
 /// </summary>
 /// <remarks>
 /// This is an internal (unsafe) version that takes an IntPtr.
 /// </remarks>
 /// <param name="sesid">The session to use.</param>
 /// <param name="tableid">The cursor to create the key on.</param>
 /// <param name="data">Column data for the current key column of the current index.</param>
 /// <param name="dataSize">Size of the data.</param>
 /// <param name="grbit">Key options.</param>
 internal static void JetMakeKey(JET_SESID sesid, JET_TABLEID tableid, IntPtr data, int dataSize, MakeKeyGrbit grbit)
 {
     Api.Check(Impl.JetMakeKey(sesid, tableid, data, dataSize, grbit));
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Retrieves a single column value from the current record. The record is that
 /// record associated with the index entry at the current position of the cursor.
 /// Alternatively, this function can retrieve a column from a record being created
 /// in the cursor copy buffer. This function can also retrieve column data from an
 /// index entry that references the current record. In addition to retrieving the
 /// actual column value, JetRetrieveColumn can also be used to retrieve the size
 /// of a column, before retrieving the column data itself so that application
 /// buffers can be sized appropriately.
 /// </summary>
 /// <remarks>
 /// This is an internal-use version that takes an IntPtr.
 /// </remarks>
 /// <param name="sesid">The session to use.</param>
 /// <param name="tableid">The cursor to retrieve the column from.</param>
 /// <param name="columnid">The columnid to retrieve.</param>
 /// <param name="data">The data buffer to be retrieved into.</param>
 /// <param name="dataSize">The size of the data buffer.</param>
 /// <param name="actualDataSize">Returns the actual size of the data buffer.</param>
 /// <param name="grbit">Retrieve column options.</param>
 /// <param name="retinfo">
 /// If pretinfo is give as NULL then the function behaves as though an itagSequence
 /// of 1 and an ibLongValue of 0 (zero) were given. This causes column retrieval to
 /// retrieve the first value of a multi-valued column, and to retrieve long data at
 /// offset 0 (zero).
 /// </param>
 /// <returns>An ESENT warning code.</returns>
 internal static JET_wrn JetRetrieveColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, out int actualDataSize, RetrieveColumnGrbit grbit, JET_RETINFO retinfo)
 {
     return(Api.Check(Impl.JetRetrieveColumn(sesid, tableid, columnid, data, dataSize, out actualDataSize, grbit, retinfo)));
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Recursive RetrieveColumns method for data pinning. This should pin a buffer and
        /// call the inherited RetrieveColumns method.
        /// </summary>
        /// <param name="sesid">The session to use.</param>
        /// <param name="tableid">
        /// The table to retrieve the columns from.
        /// </param>
        /// <param name="columnValues">
        /// Column values to retrieve.
        /// </param>
        internal static void RetrieveColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues)
        {
            const int MaxColumnValues = 1024;

            if (columnValues.Length > MaxColumnValues)
            {
                throw new ArgumentOutOfRangeException("columnValues", columnValues.Length, "Too many column values");
            }

            unsafe
            {
                byte[] buffer = null;
                NATIVE_RETRIEVECOLUMN *nativeRetrievecolumns = stackalloc NATIVE_RETRIEVECOLUMN[columnValues.Length];

                try
                {
                    buffer = Caches.ColumnCache.Allocate();
                    Debug.Assert(MaxColumnValues * 16 < buffer.Length, "Maximum size of fixed columns could exceed buffer size");

                    fixed(byte *pinnedBuffer = buffer)
                    {
                        byte *currentBuffer            = pinnedBuffer;
                        int   numVariableLengthColumns = columnValues.Length;

                        // First the fixed-size columns
                        for (int i = 0; i < columnValues.Length; ++i)
                        {
                            if (0 != columnValues[i].Size)
                            {
                                columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
                                nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
                                nativeRetrievecolumns[i].cbData = checked ((uint)columnValues[i].Size);

                                currentBuffer += nativeRetrievecolumns[i].cbData;
                                Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");

                                numVariableLengthColumns--;
                            }
                        }

                        // Now the variable-length columns
                        if (numVariableLengthColumns > 0)
                        {
                            int bufferUsed      = checked ((int)(currentBuffer - pinnedBuffer));
                            int bufferRemaining = checked (buffer.Length - bufferUsed);
                            int bufferPerColumn = bufferRemaining / numVariableLengthColumns;
                            Debug.Assert(bufferPerColumn > 0, "Not enough buffer left to retrieve variable length columns");

                            // Now the variable-size columns
                            for (int i = 0; i < columnValues.Length; ++i)
                            {
                                if (0 == columnValues[i].Size)
                                {
                                    columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
                                    nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
                                    nativeRetrievecolumns[i].cbData = checked ((uint)bufferPerColumn);
                                    currentBuffer += nativeRetrievecolumns[i].cbData;
                                    Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");
                                }
                            }
                        }

                        // Retrieve the columns
                        Api.Check(Api.Impl.JetRetrieveColumns(sesid, tableid, nativeRetrievecolumns, columnValues.Length));

                        // Propagate the warnings and output.
                        for (int i = 0; i < columnValues.Length; ++i)
                        {
                            columnValues[i].Error        = (JET_wrn)nativeRetrievecolumns[i].err;
                            columnValues[i].ItagSequence = (int)nativeRetrievecolumns[i].itagSequence;
                        }

                        // Now parse out the columns that were retrieved successfully
                        for (int i = 0; i < columnValues.Length; ++i)
                        {
                            if (nativeRetrievecolumns[i].err != (int)JET_wrn.BufferTruncated)
                            {
                                byte *columnBuffer = (byte *)nativeRetrievecolumns[i].pvData;
                                int   startIndex   = checked ((int)(columnBuffer - pinnedBuffer));
                                columnValues[i].GetValueFromBytes(
                                    buffer,
                                    startIndex,
                                    checked ((int)nativeRetrievecolumns[i].cbActual),
                                    nativeRetrievecolumns[i].err);
                            }
                        }
                    }

                    // Finally retrieve the buffers where the columns weren't large enough.
                    RetrieveTruncatedBuffers(sesid, tableid, columnValues, nativeRetrievecolumns);
                }
                finally
                {
                    if (buffer != null)
                    {
                        Caches.ColumnCache.Free(ref buffer);
                    }
                }
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// The JetSetColumn function modifies a single column value in a modified record to be inserted or to
 /// update the current record. It can overwrite an existing value, add a new value to a sequence of
 /// values in a multi-valued column, remove a value from a sequence of values in a multi-valued column,
 /// or update all or part of a long value, a column of type JET_coltyp.LongText or JET_coltyp.LongBinary.
 /// </summary>
 /// <remarks>
 /// This method takes an IntPtr and is intended for internal use only.
 /// </remarks>
 /// <param name="sesid">The session which is performing the update.</param>
 /// <param name="tableid">The cursor to update. An update should be prepared.</param>
 /// <param name="columnid">The columnid to set.</param>
 /// <param name="data">The data to set.</param>
 /// <param name="dataSize">The size of data to set.</param>
 /// <param name="grbit">SetColumn options.</param>
 /// <param name="setinfo">Used to specify itag or long-value offset.</param>
 /// <returns>A warning value.</returns>
 internal static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, SetColumnGrbit grbit, JET_SETINFO setinfo)
 {
     return(Api.Check(Impl.JetSetColumn(sesid, tableid, columnid, data, dataSize, grbit, setinfo)));
 }