/////////////////////////////////////////////////////////////////////// /// <summary> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </summary> /// <param name="table"> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </param> /// <param name="index"> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </param> /// <returns> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </returns> public override SQLiteErrorCode BestIndex( SQLiteVirtualTable table, SQLiteIndex index ) { CheckDisposed(); return(GetMethodResultCode("BestIndex")); }
/////////////////////////////////////////////////////////////////////// /// <summary> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </summary> /// <param name="table"> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </param> /// <param name="index"> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </param> /// <returns> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </returns> public override SQLiteErrorCode BestIndex( SQLiteVirtualTable table, SQLiteIndex index ) { CheckDisposed(); if (!table.BestIndex(index)) { SetTableError(table, String.Format(CultureInfo.CurrentCulture, "failed to select best index for virtual table \"{0}\"", table.TableName)); return(SQLiteErrorCode.Error); } return(SQLiteErrorCode.Ok); }
/////////////////////////////////////////////////////////////////////// /// <summary> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </summary> /// <param name="table"> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </param> /// <param name="index"> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </param> /// <returns> /// See the <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </returns> public override SQLiteErrorCode BestIndex( SQLiteVirtualTable table, SQLiteIndex index ) { CheckDisposed(); return GetMethodResultCode("BestIndex"); }
/////////////////////////////////////////////////////////////////////// /// <summary> /// This method is called in response to the /// <see cref="ISQLiteNativeModule.xBestIndex" /> method. /// </summary> /// <param name="table"> /// The <see cref="SQLiteVirtualTable" /> object instance associated /// with this virtual table. /// </param> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance containing all the /// data for the inputs and outputs relating to index selection. /// </param> /// <returns> /// A standard SQLite return code. /// </returns> public abstract SQLiteErrorCode BestIndex( SQLiteVirtualTable table, SQLiteIndex index );
/////////////////////////////////////////////////////////////////////// /// <summary> /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the default estimated rows. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedRows( SQLiteIndex index ) { return SetEstimatedRows(index, null); }
/////////////////////////////////////////////////////////////////////// /// <summary> /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the specified estimated rows. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <param name="estimatedRows"> /// The estimated rows value to use. Using a null value means that the /// default value provided by the SQLite core library should be used. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedRows( SQLiteIndex index, long? estimatedRows ) { if ((index == null) || (index.Outputs == null)) return false; index.Outputs.EstimatedRows = estimatedRows; return true; }
/////////////////////////////////////////////////////////////////////// #region Index Handling Helper Methods /// <summary> /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the specified estimated cost. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <param name="estimatedCost"> /// The estimated cost value to use. Using a null value means that the /// default value provided by the SQLite core library should be used. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedCost( SQLiteIndex index, double? estimatedCost ) { if ((index == null) || (index.Outputs == null)) return false; index.Outputs.EstimatedCost = estimatedCost; return true; }
/////////////////////////////////////////////////////////////////////// #region Public Methods /// <summary> /// This method should normally be used by the /// <see cref="ISQLiteManagedModule.BestIndex" /> method in order to /// perform index selection based on the constraints provided by the /// SQLite core library. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance containing all the /// data for the inputs and outputs relating to index selection. /// </param> /// <returns> /// Non-zero upon success. /// </returns> public virtual bool BestIndex( SQLiteIndex index ) { CheckDisposed(); this.index = index; return true; }
/////////////////////////////////////////////////////////////////////// /// <summary> /// Populates the outputs of a pre-allocated native sqlite3_index_info /// structure using an existing <see cref="SQLiteIndex" /> object /// instance. /// </summary> /// <param name="index"> /// The existing <see cref="SQLiteIndex" /> object instance containing /// the output data to use. /// </param> /// <param name="pIndex"> /// The native pointer to the pre-allocated native sqlite3_index_info /// structure. /// </param> internal static void ToIntPtr( SQLiteIndex index, IntPtr pIndex ) { if ((index == null) || (index.Inputs == null) || (index.Inputs.Constraints == null) || (index.Outputs == null) || (index.Outputs.ConstraintUsages == null)) { return; } if (pIndex == IntPtr.Zero) return; int offset = 0; int nConstraint = SQLiteMarshal.ReadInt32(pIndex, offset); if (nConstraint != index.Inputs.Constraints.Length) return; if (nConstraint != index.Outputs.ConstraintUsages.Length) return; offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), IntPtr.Size); offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size, sizeof(int)); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), IntPtr.Size); offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size, sizeof(int)); IntPtr pConstraintUsage = SQLiteMarshal.ReadIntPtr(pIndex, offset); int sizeOfConstraintUsageType = Marshal.SizeOf(typeof( UnsafeNativeMethods.sqlite3_index_constraint_usage)); for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++) { UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage = new UnsafeNativeMethods.sqlite3_index_constraint_usage( index.Outputs.ConstraintUsages[iConstraint]); Marshal.StructureToPtr( constraintUsage, SQLiteMarshal.IntPtrForOffset( pConstraintUsage, iConstraint * sizeOfConstraintUsageType), false); } offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size, sizeof(int)); SQLiteMarshal.WriteInt32(pIndex, offset, index.Outputs.IndexNumber); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), IntPtr.Size); SQLiteMarshal.WriteIntPtr(pIndex, offset, SQLiteString.Utf8IntPtrFromString(index.Outputs.IndexString)); offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size, sizeof(int)); // // NOTE: We just allocated the IndexString field; therefore, we // need to set the NeedToFreeIndexString field to non-zero. // SQLiteMarshal.WriteInt32(pIndex, offset, 1); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), sizeof(int)); SQLiteMarshal.WriteInt32(pIndex, offset, index.Outputs.OrderByConsumed); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), sizeof(double)); if (index.Outputs.EstimatedCost.HasValue) { SQLiteMarshal.WriteDouble(pIndex, offset, index.Outputs.EstimatedCost.GetValueOrDefault()); } if (index.Outputs.CanUseEstimatedRows() && index.Outputs.EstimatedRows.HasValue) { SQLiteMarshal.WriteInt64(pIndex, offset, index.Outputs.EstimatedRows.GetValueOrDefault()); } }
/////////////////////////////////////////////////////////////////////// #region Internal Marshal Helper Methods /// <summary> /// Converts a native pointer to a native sqlite3_index_info structure /// into a new <see cref="SQLiteIndex" /> object instance. /// </summary> /// <param name="pIndex"> /// The native pointer to the native sqlite3_index_info structure to /// convert. /// </param> /// <param name="index"> /// Upon success, this parameter will be modified to contain the newly /// created <see cref="SQLiteIndex" /> object instance. /// </param> internal static void FromIntPtr( IntPtr pIndex, ref SQLiteIndex index ) { if (pIndex == IntPtr.Zero) return; int offset = 0; int nConstraint = SQLiteMarshal.ReadInt32(pIndex, offset); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), IntPtr.Size); IntPtr pConstraint = SQLiteMarshal.ReadIntPtr(pIndex, offset); offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size, sizeof(int)); int nOrderBy = SQLiteMarshal.ReadInt32(pIndex, offset); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), IntPtr.Size); IntPtr pOrderBy = SQLiteMarshal.ReadIntPtr(pIndex, offset); index = new SQLiteIndex(nConstraint, nOrderBy); Type indexConstraintType = typeof( UnsafeNativeMethods.sqlite3_index_constraint); int sizeOfConstraintType = Marshal.SizeOf(indexConstraintType); for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++) { IntPtr pOffset = SQLiteMarshal.IntPtrForOffset( pConstraint, iConstraint * sizeOfConstraintType); UnsafeNativeMethods.sqlite3_index_constraint constraint = (UnsafeNativeMethods.sqlite3_index_constraint) Marshal.PtrToStructure(pOffset, indexConstraintType); index.Inputs.Constraints[iConstraint] = new SQLiteIndexConstraint(constraint); } Type indexOrderByType = typeof( UnsafeNativeMethods.sqlite3_index_orderby); int sizeOfOrderByType = Marshal.SizeOf(indexOrderByType); for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++) { IntPtr pOffset = SQLiteMarshal.IntPtrForOffset( pOrderBy, iOrderBy * sizeOfOrderByType); UnsafeNativeMethods.sqlite3_index_orderby orderBy = (UnsafeNativeMethods.sqlite3_index_orderby) Marshal.PtrToStructure(pOffset, indexOrderByType); index.Inputs.OrderBys[iOrderBy] = new SQLiteIndexOrderBy(orderBy); } }
/////////////////////////////////////////////////////////////////////// /// <summary> /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the default estimated cost. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedCost( SQLiteIndex index ) { return SetEstimatedCost(index, SQLiteIndex.DefaultEstimatedCost); }